aws-cdk

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS 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
    cdk synth
    , tests,
    cdk diff
    , and
    cdk deploy
在以下场景中使用此技能:
  • 在TypeScript中创建或重构CDK应用、堆栈或可重用构造
  • 在L1、L2和L3构造之间进行选择
  • 构建面向无服务器、网络或安全领域的AWS基础设施
  • 连接多堆栈应用和感知环境的部署
  • 通过
    cdk synth
    、测试、
    cdk diff
    cdk deploy
    验证基础设施变更

Instructions

操作指南

1. Project Initialization

1. 项目初始化

bash
undefined
bash
undefined

Create 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
undefined
my-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
undefined

2. 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. 构造层级

LevelDescriptionUse When
L1 (
Cfn*
)
Direct CloudFormation mapping, full controlNeed properties not exposed by L2
L2Curated with sensible defaults and helper methodsStandard resource provisioning (recommended)
L3 (Patterns)Multi-resource architecturesCommon patterns like
LambdaRestApi
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 (
Cfn*
)
直接映射CloudFormation,完全可控需要L2未暴露的属性时
L2经过精心设计,包含合理默认值和辅助方法标准资源配置(推荐)
L3(模式)多资源架构常见模式如
LambdaRestApi
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 setup
bash
cdk synth          # 生成CloudFormation模板
cdk diff           # 对比已部署资源与本地变更
cdk deploy         # 将堆栈部署到AWS
cdk deploy --all   # 部署所有堆栈
cdk destroy        # 销毁堆栈
cdk ls             # 列出应用中的所有堆栈
cdk doctor         # 检查环境配置

5. Recommended Delivery Loop

5. 推荐交付流程

  1. Model the stack
    • Start with L2 constructs and extract repeated logic into custom constructs.
  2. 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
      .
  3. 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.
  4. 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
      RemovalPolicy
      , then rerun
      cdk diff
      .
  5. Run
    cdk deploy
    • Checkpoint: the stack reaches
      CREATE_COMPLETE
      or
      UPDATE_COMPLETE
      .
    • If deploy fails: inspect CloudFormation events, fix quotas, permissions, export conflicts, or bootstrap issues, then retry
      cdk deploy
      .
  6. Verify runtime outcomes
    • Confirm stack outputs, endpoints, alarms, and integrations behave as expected before moving on.
  1. 建模堆栈
    • 从L2构造开始,将重复逻辑提取到自定义构造中。
  2. 运行
    cdk synth
    • 检查点:合成成功,无缺失导入、无效属性、缺失上下文或未解析引用。
    • 如果失败:修复构造配置或上下文值,然后重新运行
      cdk synth
  3. 运行基础设施测试
    • 检查点:断言覆盖IAM范围、有状态资源和关键输出。
    • 如果测试失败:更新堆栈或测试预期,然后重新运行测试套件。
  4. 运行
    cdk diff
    • 检查点:审查IAM权限扩大、资源替换、导出变更以及有状态资源的删除操作。
    • 如果差异存在风险:调整名称、依赖关系或
      RemovalPolicy
      ,然后重新运行
      cdk diff
  5. 运行
    cdk deploy
    • 检查点:堆栈达到
      CREATE_COMPLETE
      UPDATE_COMPLETE
      状态。
    • 如果部署失败:检查CloudFormation事件,修复配额、权限、导出冲突或引导问题,然后重试
      cdk deploy
  6. 验证运行时结果
    • 在继续之前,确认堆栈输出、端点、告警和集成的行为符合预期。

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

最佳实践

  1. One concern per stack — Separate network, compute, storage, and monitoring.
  2. Prefer L2 constructs — Drop to
    Cfn*
    only when you need unsupported properties.
  3. Set explicit environments — Pass
    env
    with account and region; avoid implicit production targets.
  4. Use grant helpers — Prefer
    .grant*()
    over handwritten IAM where possible.
  5. Review the diff before deploy — Treat IAM expansion, replacement, and deletes as mandatory checkpoints.
  6. Test infrastructure — Cover critical resources with fine-grained assertions.
  7. Avoid hardcoded values — Use context, parameters, or environment variables.
  8. Use the right
    RemovalPolicy
    RETAIN
    for production data,
    DESTROY
    only for disposable environments.
  1. 每个堆栈对应一个关注点 — 分离网络、计算、存储和监控堆栈。
  2. 优先使用L2构造 — 仅在需要不支持的属性时才使用
    Cfn*
  3. 设置明确的环境 — 传递包含账号和区域的
    env
    参数;避免隐式指向生产环境。
  4. 使用授权辅助方法 — 尽可能优先使用
    .grant*()
    而非手动编写IAM策略。
  5. 部署前审查差异 — 将IAM权限扩大、资源替换和删除操作视为强制检查点。
  6. 测试基础设施 — 用细粒度断言覆盖关键资源。
  7. 避免硬编码值 — 使用上下文、参数或环境变量。
  8. 选择合适的
    RemovalPolicy
    — 生产数据使用
    RETAIN
    ,仅在一次性环境中使用
    DESTROY

Constraints and Warnings

约束与警告

  • CloudFormation limits — Max 500 resources per stack; split large apps into multiple stacks
  • Synthesis is not deployment
    cdk synth
    only generates templates;
    cdk deploy
    applies changes
  • Cross-stack references create CloudFormation exports; removing them requires careful ordering
  • Stateful resources (RDS, DynamoDB, S3 with data) — Always set
    removalPolicy: RETAIN
    in production
  • Bootstrap required — Run
    cdk bootstrap
    once per account/region before first deploy
  • 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
references/
directory:
  • 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