aws-cdk
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAWS CDK TypeScript
AWS CDK TypeScript
Overview
概述
Use this skill to build AWS infrastructure in TypeScript with reusable constructs, safe defaults, and a validation-first delivery loop.
使用此技能,通过可重用构造、安全默认配置和优先验证的交付流程,用TypeScript构建AWS基础设施。
When to Use
适用场景
Use this skill when:
- Creating or refactoring a CDK app, stack, or reusable construct in TypeScript
- Choosing between L1, L2, and L3 constructs
- Building serverless, networking, or security-focused AWS infrastructure
- Wiring multi-stack applications and environment-aware deployments
- Validating infrastructure changes with , tests,
cdk synth, andcdk diffcdk deploy
在以下场景中使用此技能:
- 在TypeScript中创建或重构CDK应用、堆栈或可重用构造
- 在L1、L2和L3构造之间进行选择
- 构建面向无服务器、网络或安全领域的AWS基础设施
- 连接多堆栈应用和感知环境的部署
- 通过、测试、
cdk synth和cdk diff验证基础设施变更cdk deploy
Instructions
操作指南
1. Project Initialization
1. 项目初始化
bash
undefinedbash
undefinedCreate a new CDK app
创建新的CDK应用
npx cdk init app --language typescript
npx cdk init app --language typescript
Project structure
项目结构
my-cdk-app/
├── bin/
│ └── my-cdk-app.ts # App entry point (instantiates stacks)
├── lib/
│ └── my-cdk-app-stack.ts # Stack definition
├── test/
│ └── my-cdk-app.test.ts # Tests
├── cdk.json # CDK configuration
├── tsconfig.json
└── package.json
undefinedmy-cdk-app/
├── bin/
│ └── my-cdk-app.ts # 应用入口点(实例化堆栈)
├── lib/
│ └── my-cdk-app-stack.ts # 堆栈定义
├── test/
│ └── my-cdk-app.test.ts # 测试文件
├── cdk.json # CDK配置文件
├── tsconfig.json
└── package.json
undefined2. Core Architecture
2. 核心架构
typescript
import { App, Stack, StackProps, CfnOutput, RemovalPolicy } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
// Define a reusable stack
class StorageStack extends Stack {
public readonly bucketArn: string;
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, 'DataBucket', {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: RemovalPolicy.RETAIN,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});
this.bucketArn = bucket.bucketArn;
new CfnOutput(this, 'BucketName', { value: bucket.bucketName });
}
}
// App entry point
const app = new App();
new StorageStack(app, 'DevStorage', {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: 'us-east-1' },
tags: { Environment: 'dev' },
});
new StorageStack(app, 'ProdStorage', {
env: { account: '123456789012', region: 'eu-west-1' },
tags: { Environment: 'prod' },
terminationProtection: true,
});
app.synth();typescript
import { App, Stack, StackProps, CfnOutput, RemovalPolicy } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
// 定义可重用堆栈
class StorageStack extends Stack {
public readonly bucketArn: string;
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, 'DataBucket', {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: RemovalPolicy.RETAIN,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});
this.bucketArn = bucket.bucketArn;
new CfnOutput(this, 'BucketName', { value: bucket.bucketName });
}
}
// 应用入口点
const app = new App();
new StorageStack(app, 'DevStorage', {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: 'us-east-1' },
tags: { Environment: 'dev' },
});
new StorageStack(app, 'ProdStorage', {
env: { account: '123456789012', region: 'eu-west-1' },
tags: { Environment: 'prod' },
terminationProtection: true,
});
app.synth();3. Construct Levels
3. 构造层级
| Level | Description | Use When |
|---|---|---|
L1 ( | Direct CloudFormation mapping, full control | Need properties not exposed by L2 |
| L2 | Curated with sensible defaults and helper methods | Standard resource provisioning (recommended) |
| L3 (Patterns) | Multi-resource architectures | Common patterns like |
typescript
// L1 — Raw CloudFormation
new s3.CfnBucket(this, 'L1Bucket', { bucketName: 'my-l1-bucket' });
// L2 — Sensible defaults + grant helpers
const bucket = new s3.Bucket(this, 'L2Bucket', { versioned: true });
bucket.grantRead(myLambda);
// L3 — Multi-resource pattern
new apigateway.LambdaRestApi(this, 'Api', { handler: myLambda });| 层级 | 描述 | 适用场景 |
|---|---|---|
L1 ( | 直接映射CloudFormation,完全可控 | 需要L2未暴露的属性时 |
| L2 | 经过精心设计,包含合理默认值和辅助方法 | 标准资源配置(推荐) |
| L3(模式) | 多资源架构 | 常见模式如 |
typescript
// L1 — 原生CloudFormation
new s3.CfnBucket(this, 'L1Bucket', { bucketName: 'my-l1-bucket' });
// L2 — 合理默认值 + 授权辅助方法
const bucket = new s3.Bucket(this, 'L2Bucket', { versioned: true });
bucket.grantRead(myLambda);
// L3 — 多资源模式
new apigateway.LambdaRestApi(this, 'Api', { handler: myLambda });4. CDK Lifecycle Commands
4. CDK生命周期命令
bash
cdk synth # Synthesize CloudFormation template
cdk diff # Compare deployed vs local changes
cdk deploy # Deploy stack(s) to AWS
cdk deploy --all # Deploy all stacks
cdk destroy # Tear down stack(s)
cdk ls # List all stacks in the app
cdk doctor # Check environment setupbash
cdk synth # 生成CloudFormation模板
cdk diff # 对比已部署资源与本地变更
cdk deploy # 将堆栈部署到AWS
cdk deploy --all # 部署所有堆栈
cdk destroy # 销毁堆栈
cdk ls # 列出应用中的所有堆栈
cdk doctor # 检查环境配置5. Recommended Delivery Loop
5. 推荐交付流程
-
Model the stack
- Start with L2 constructs and extract repeated logic into custom constructs.
-
Run
cdk synth- Checkpoint: synthesis succeeds with no missing imports, invalid props, missing context, or unresolved references.
- If it fails: fix the construct configuration or context values, then rerun .
cdk synth
-
Run infrastructure tests
- Checkpoint: assertions cover IAM scope, stateful resources, and critical outputs.
- If tests fail: update the stack or test expectations, then rerun the test suite.
-
Run
cdk diff- Checkpoint: review IAM broadening, resource replacement, export changes, and deletes on stateful resources.
- If the diff is risky: adjust names, dependencies, or , then rerun
RemovalPolicy.cdk diff
-
Run
cdk deploy- Checkpoint: the stack reaches or
CREATE_COMPLETE.UPDATE_COMPLETE - If deploy fails: inspect CloudFormation events, fix quotas, permissions, export conflicts, or bootstrap issues, then retry .
cdk deploy
- Checkpoint: the stack reaches
-
Verify runtime outcomes
- Confirm stack outputs, endpoints, alarms, and integrations behave as expected before moving on.
-
建模堆栈
- 从L2构造开始,将重复逻辑提取到自定义构造中。
-
运行
cdk synth- 检查点:合成成功,无缺失导入、无效属性、缺失上下文或未解析引用。
- 如果失败:修复构造配置或上下文值,然后重新运行。
cdk synth
-
运行基础设施测试
- 检查点:断言覆盖IAM范围、有状态资源和关键输出。
- 如果测试失败:更新堆栈或测试预期,然后重新运行测试套件。
-
运行
cdk diff- 检查点:审查IAM权限扩大、资源替换、导出变更以及有状态资源的删除操作。
- 如果差异存在风险:调整名称、依赖关系或,然后重新运行
RemovalPolicy。cdk diff
-
运行
cdk deploy- 检查点:堆栈达到或
CREATE_COMPLETE状态。UPDATE_COMPLETE - 如果部署失败:检查CloudFormation事件,修复配额、权限、导出冲突或引导问题,然后重试。
cdk deploy
- 检查点:堆栈达到
-
验证运行时结果
- 在继续之前,确认堆栈输出、端点、告警和集成的行为符合预期。
6. Cross-Stack References
6. 跨堆栈引用
typescript
// Stack A exports a value
class NetworkStack extends Stack {
public readonly vpc: ec2.Vpc;
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
this.vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 2 });
}
}
// Stack B imports it via props
interface AppStackProps extends StackProps {
vpc: ec2.Vpc;
}
class AppStack extends Stack {
constructor(scope: Construct, id: string, props: AppStackProps) {
super(scope, id, props);
new lambda.Function(this, 'Fn', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda'),
vpc: props.vpc,
});
}
}
// Wire them together
const network = new NetworkStack(app, 'Network');
new AppStack(app, 'App', { vpc: network.vpc });typescript
// 堆栈A导出值
class NetworkStack extends Stack {
public readonly vpc: ec2.Vpc;
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
this.vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 2 });
}
}
// 堆栈B通过属性导入
interface AppStackProps extends StackProps {
vpc: ec2.Vpc;
}
class AppStack extends Stack {
constructor(scope: Construct, id: string, props: AppStackProps) {
super(scope, id, props);
new lambda.Function(this, 'Fn', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda'),
vpc: props.vpc,
});
}
}
// 将它们关联起来
const network = new NetworkStack(app, 'Network');
new AppStack(app, 'App', { vpc: network.vpc });Examples
示例
Example 1: Serverless API
示例1:无服务器API
typescript
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
class ServerlessApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const table = new dynamodb.Table(this, 'Items', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
const fn = new lambda.Function(this, 'Handler', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda'),
environment: { TABLE_NAME: table.tableName },
});
table.grantReadWriteData(fn);
new apigateway.LambdaRestApi(this, 'Api', { handler: fn });
}
}typescript
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
class ServerlessApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const table = new dynamodb.Table(this, 'Items', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
const fn = new lambda.Function(this, 'Handler', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda'),
environment: { TABLE_NAME: table.tableName },
});
table.grantReadWriteData(fn);
new apigateway.LambdaRestApi(this, 'Api', { handler: fn });
}
}Example 2: CDK Assertion Test
示例2:CDK断言测试
typescript
import { Template } from 'aws-cdk-lib/assertions';
import { App } from 'aws-cdk-lib';
import { ServerlessApiStack } from '../lib/serverless-api-stack';
test('creates DynamoDB table with PAY_PER_REQUEST', () => {
const app = new App();
const stack = new ServerlessApiStack(app, 'TestStack');
const template = Template.fromStack(stack);
template.hasResourceProperties('AWS::DynamoDB::Table', {
BillingMode: 'PAY_PER_REQUEST',
});
template.resourceCountIs('AWS::Lambda::Function', 1);
});typescript
import { Template } from 'aws-cdk-lib/assertions';
import { App } from 'aws-cdk-lib';
import { ServerlessApiStack } from '../lib/serverless-api-stack';
test('creates DynamoDB table with PAY_PER_REQUEST', () => {
const app = new App();
const stack = new ServerlessApiStack(app, 'TestStack');
const template = Template.fromStack(stack);
template.hasResourceProperties('AWS::DynamoDB::Table', {
BillingMode: 'PAY_PER_REQUEST',
});
template.resourceCountIs('AWS::Lambda::Function', 1);
});Best Practices
最佳实践
- One concern per stack — Separate network, compute, storage, and monitoring.
- Prefer L2 constructs — Drop to only when you need unsupported properties.
Cfn* - Set explicit environments — Pass with account and region; avoid implicit production targets.
env - Use grant helpers — Prefer over handwritten IAM where possible.
.grant*() - Review the diff before deploy — Treat IAM expansion, replacement, and deletes as mandatory checkpoints.
- Test infrastructure — Cover critical resources with fine-grained assertions.
- Avoid hardcoded values — Use context, parameters, or environment variables.
- Use the right —
RemovalPolicyfor production data,RETAINonly for disposable environments.DESTROY
- 每个堆栈对应一个关注点 — 分离网络、计算、存储和监控堆栈。
- 优先使用L2构造 — 仅在需要不支持的属性时才使用。
Cfn* - 设置明确的环境 — 传递包含账号和区域的参数;避免隐式指向生产环境。
env - 使用授权辅助方法 — 尽可能优先使用而非手动编写IAM策略。
.grant*() - 部署前审查差异 — 将IAM权限扩大、资源替换和删除操作视为强制检查点。
- 测试基础设施 — 用细粒度断言覆盖关键资源。
- 避免硬编码值 — 使用上下文、参数或环境变量。
- 选择合适的— 生产数据使用
RemovalPolicy,仅在一次性环境中使用RETAIN。DESTROY
Constraints and Warnings
约束与警告
- CloudFormation limits — Max 500 resources per stack; split large apps into multiple stacks
- Synthesis is not deployment — only generates templates;
cdk synthapplies changescdk deploy - Cross-stack references create CloudFormation exports; removing them requires careful ordering
- Stateful resources (RDS, DynamoDB, S3 with data) — Always set in production
removalPolicy: RETAIN - Bootstrap required — Run once per account/region before first deploy
cdk bootstrap - Asset bundling — Lambda code and Docker images are uploaded to the CDK bootstrap bucket
- CloudFormation限制 — 每个堆栈最多500个资源;大型应用需拆分为多个堆栈
- 合成不等于部署 — 仅生成模板;
cdk synth才会应用变更cdk deploy - 跨堆栈引用会创建CloudFormation导出;删除它们需要谨慎的顺序
- 有状态资源(RDS、DynamoDB、包含数据的S3)— 生产环境中始终设置
removalPolicy: RETAIN - 需要引导 — 首次部署前,需在每个账号/区域运行一次
cdk bootstrap - 资产打包 — Lambda代码和Docker镜像会上传到CDK引导存储桶
References
参考资料
Detailed implementation guides are available in the directory:
references/- Core Concepts — App lifecycle, stacks, constructs, environments, assets
- Serverless Patterns — Lambda, API Gateway, DynamoDB, S3 events, Step Functions
- Networking & VPC — VPC design, subnets, NAT, security groups, VPC endpoints
- Security Hardening — IAM, KMS, Secrets Manager, WAF, compliance
- Testing Strategies — Assertions, snapshots, integration tests, CDK Nag
详细的实现指南可在目录中找到:
references/- 核心概念 — 应用生命周期、堆栈、构造、环境、资产
- 无服务器模式 — Lambda、API Gateway、DynamoDB、S3事件、Step Functions
- 网络与VPC — VPC设计、子网、NAT、安全组、VPC端点
- 安全加固 — IAM、KMS、Secrets Manager、WAF、合规性
- 测试策略 — 断言、快照、集成测试、CDK Nag