使用 TypeScript 或 Python 通过 CDK 编写、部署和排查 AWS 基础设施问题。涵盖最佳实践、堆栈架构和构造模式。在编写 CDK 构造、引导环境、运行 cdk deploy/synth/diff、修复 CDK 或 CloudFormation 错误、规划堆栈结构、导入现有资源、解决漂移或重构堆栈而不替换资源时,始终使用此技能。
AWS CDK
概述
CDK 构造编写、部署工作流、合规性、漂移、资源导入、安全重构以及 CDK CLI/CloudFormation 错误排查的领域专业知识。
何时不使用: 原始 CloudFormation YAML/JSON、SAM、Terraform/Pulumi、CDK Pipelines 之外的 CI/CD。请使用内置知识或专门技能处理这些情况。
关键警告
死锁: 移除跨堆栈引用会导致部署死锁(Export ... cannot be deleted as it is in use by ...)。首选修复方法:先削弱引用——CrossStackReferences.of($RESOURCE).produce(ReferenceStrength.BOTH) 然后 WEAK,再移除(三次部署)。传统回退方案:两次部署的 this.exportValue() 方法。参见 troubleshooting-deployment。
构造 ID 更改导致资源替换: 重命名或移动构造会更改其逻辑 ID → CloudFormation 替换资源(对有状态资源造成数据丢失)。部署前务必执行 cdk diff。参见 refactor-and-prevent-replacement。
UPDATE_ROLLBACK_FAILED: 堆栈卡住。使用 cdk rollback $STACK 或 cdk rollback $STACK --orphan <LogicalId> 修复。参见 troubleshooting-deployment。
非空 S3 存储桶在销毁后仍然存在: 必须同时设置 removalPolicy: DESTROY 和 autoDeleteObjects: true。带版本控制的存储桶更糟——即使看似删除,删除标记仍然存在。
常见工作流
| 任务 | 快速命令 | 详情 |
|---|---|---|
| 引导 | cdk bootstrap aws://$ACCOUNT/$REGION |
bootstrap-and-project-setup |
| 新建 TS 项目 | cdk init app --language typescript — 使用 tsx、eslint-plugin-awscdk |
bootstrap-and-project-setup |
| 新建 Python 项目 | cdk init app --language python — 锁定依赖,使用虚拟环境 |
bootstrap-and-project-setup |
| 部署 | cdk synth --strict → cdk diff → cdk deploy |
部署到生产环境前务必执行 diff |
| cdk-nag | Aspects.of(app).add(new AwsSolutionsChecks()) |
compliance-and-drift |
| 漂移 | cdk drift $STACK(CI 中使用 --fail) |
compliance-and-drift |
| 导入资源 | cdk import(交互式或 CI 中使用 --resource-mapping)、cdk deploy --import-existing-resources |
import-and-migrate |
| 安全重构 | cdk refactor --unstable=refactor — 同一部署中不进行属性更改 |
refactor-and-prevent-replacement |
故障排查
| 错误 | 原因 → 修复 |
|---|---|
| DeployFailed / DeploymentError | CDK 错误不是根本原因。执行 cdk deploy $STACK --verbose,然后 cdk --unstable=diagnose diagnose $STACK(CLI ≥ 2.1120.0);否则执行 aws cloudformation describe-events --stack-name $STACK --filters FailedEvents=true——第一个 _FAILED 事件即为原因。详情 |
| NoCredentials / ExpiredToken / AssumeRoleFailed | aws sts get-caller-identity + cdk doctor。SSO 过期、缺少 env、缺少 sts:AssumeRole。详情 |
| 资产错误(CannotFindAsset、FailedToBundleAsset、AssetBuildFailed、AssetPublishFailed) | 路径错误、Docker 未运行或引导存储桶权限问题。使用 path.join(__dirname, ...)。详情 |
| AppRequired | 在 cdk.json 中添加 "app": "npx tsx bin/my-app.ts"。详情 |
| AnnotationErrors | 修复根本问题;仅作为最后手段使用 NagSuppressions 抑制。详情 |
| ConcurrentReadLock / ConcurrentWriteLock | 执行 rm -rf cdk.out 然后重新运行。并行 CI:--output ./cdk.out.$BUILD_ID。详情 |
| BootstrapVersionValidation | 重新引导。确保所有地方 --qualifier 一致。详情 |
| DependencyCycle | 将共享资源提取到第三个堆栈,或使用 SSM 进行后期绑定。详情 |
| UnresolvedAccount | 在堆栈上设置显式的 env: { account, region }。提交 cdk.context.json。详情 |
| NoStacksMatched | CDK 使用逻辑 ID(第二个构造函数参数),而非 CFN 名称。使用 cdk list 查找 ID。详情 |
| Cannot find module(合成时) | 运行 npx tsc --noEmit,检查 cdk.json 中的 app 路径是否与 tsconfig.json 的 outDir 匹配,删除过时的 .js 文件。Python:激活虚拟环境。详情 |
| V1 导入路径 / 重复的 aws-cdk-lib | V1 的 @aws-cdk/* 导入、错误的 Construct 导入、单体仓库中的重复库副本。详情 |
| Lambda Cannot find module(运行时) | 错误的 handler 值、缺少 SDK v3 迁移、Python 依赖未打包。详情 |
| API Gateway 多阶段冲突 | 在 RestApi 上设置 deploy: false,显式创建 Deployment 和 Stage。详情 |
构造模式
优先使用 L2。当 L2 缺少某个属性时,使用 L1 搭配 Mixins/Facades。逃生口:node.defaultChild → addPropertyOverride。参见 construct-patterns。
其他资源
- 搜索 AWS 文档中的“CDK Developer Guide”、“CDK API Reference”和“CDK Pipelines”
安全考虑
- 使用 OIDC 进行 CI/CD 凭据(无静态密钥)
- 引导时使用
--custom-permissions-boundary - 使用
grant*()进行资源间 IAM 授权 - 在 CI 中使用
cdk-nag+--strict - 将有状态资源放在自己的堆栈中,并设置
terminationProtection: true - 提交
cdk.context.json






