Claude Code × AWS CloudFormation/CDK 完整指南 | 自动生成基础设施即代码
用 Claude Code 加速 AWS 基础设施即代码。CloudFormation 模板、CDK TypeScript Stack 和多 Stack 设计的可运行代码 — 基于 Masa 的真实生产经验。
“每次都要在 AWS 控制台点来点去配置基础设施,真的很烦” — 如果你有过这种感受,你并不孤单。CloudFormation 和 CDK 让基础设施可以通过代码重现,但编写这些模板需要时间。
我用 Claude Code 管理本站的基础设施(Cloudflare Pages + Workers + D1),在 AWS 业务基础设施设计中也让 Claude Code 来生成 CloudFormation/CDK 模板。原来需要数小时的模板,现在 1/5 的时间就能完成。
CloudFormation vs CDK:如何选择?
CloudFormation: 用 JSON/YAML 描述基础设施的 AWS 原生服务
CDK (Cloud Development Kit): 用 TypeScript/Python 等描述基础设施,
并转换为 CloudFormation 的框架
| 对比项 | CloudFormation | CDK |
|---|---|---|
| 语言 | JSON / YAML | TypeScript、Python、Java 等 |
| 类型安全 | 无 | 优秀(TypeScript 完全类型安全) |
| 可复用性 | 低(复制粘贴) | 高(用类和函数抽象) |
| 学习成本 | 低 | 中 |
| Claude Code 兼容性 | 优秀 | 出色 |
新项目强烈推荐 CDK TypeScript。它与 Claude Code 的配合出色,结合类型补全能生成高质量代码。
Step 1:将现有 AWS 资源转为 CloudFormation
适合想要将已有 AWS 环境事后进行代码化的场景。
claude -p "
将以下 AWS 配置转为 CloudFormation 模板(YAML)。
【当前配置】
- VPC: 10.0.0.0/16,公有子网 x2,私有子网 x2
- EC2: t3.medium,Amazon Linux 2023,部署在公有子网
- RDS: MySQL 8.0,db.t3.micro,部署在私有子网
- ALB: HTTPS(ACM 证书),转发到 EC2
- 安全组:ALB 允许 443,EC2 到 RDS 仅允许 3306
【要求】
- 环境(dev/staging/prod)可通过参数切换
- 资源名称添加环境名前缀
- 在 CloudFormation Output 中输出 ALB 的 DNS 名称
"
生成的 CloudFormation 模板(节选):
AWSTemplateFormatVersion: "2010-09-09"
Description: "Web Application Infrastructure"
Parameters:
Environment:
Type: String
AllowedValues: [dev, staging, prod]
Default: dev
DBPassword:
Type: String
NoEcho: true # 密码脱敏
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${Environment}-vpc"
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs ""]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${Environment}-public-1"
# ALB 安全组
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ALB Security Group
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Outputs:
ALBDnsName:
Value: !GetAtt ApplicationLoadBalancer.DNSName
Export:
Name: !Sub "${Environment}-alb-dns"
Step 2:用 CDK 构建 Serverless 架构
CDK 用 TypeScript 编写,逻辑复用非常方便。
# 初始化 CDK 项目
mkdir my-infra && cd my-infra
npx cdk init app --language typescript
claude -p "
在 lib/my-infra-stack.ts 中用 CDK TypeScript 实现以下 Serverless 配置。
【配置】
- API Gateway (REST API) + Lambda (Node.js 20)
- DynamoDB 表(PAY_PER_REQUEST)
- S3 存储桶(私有,启用版本控制)
- CloudFront(S3 源,支持自定义域名)
- 将 DynamoDB 表名和 S3 桶名作为环境变量传给 Lambda
- 自动为 Lambda 附加最小权限 IAM 角色
为所有资源添加适当标签,
在生产环境(NODE_ENV=production)中启用删除保护。
"
生成的 CDK 代码:
// lib/my-infra-stack.ts
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";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
export class MyInfraStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const isProd = process.env.NODE_ENV === "production";
// DynamoDB 表
const table = new dynamodb.Table(this, "AppTable", {
partitionKey: { name: "PK", type: dynamodb.AttributeType.STRING },
sortKey: { name: "SK", type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
pointInTimeRecovery: true,
deletionProtection: isProd,
removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
});
// S3 存储桶
const bucket = new s3.Bucket(this, "AssetsBucket", {
versioned: true,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
deletionProtection: isProd,
removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
});
// Lambda 函数
const apiLambda = new lambda.Function(this, "ApiLambda", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
code: lambda.Code.fromAsset("src/lambda"),
environment: {
TABLE_NAME: table.tableName,
BUCKET_NAME: bucket.bucketName,
NODE_ENV: process.env.NODE_ENV ?? "development",
},
timeout: cdk.Duration.seconds(30),
memorySize: 512,
});
// 为 Lambda 授予最小权限
table.grantReadWriteData(apiLambda);
bucket.grantReadWrite(apiLambda);
// API Gateway
const api = new apigateway.RestApi(this, "AppApi", {
restApiName: "MyApp API",
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS,
allowMethods: apigateway.Cors.ALL_METHODS,
},
});
api.root.addProxy({
defaultIntegration: new apigateway.LambdaIntegration(apiLambda),
});
// CloudFront
const distribution = new cloudfront.Distribution(this, "Distribution", {
defaultBehavior: {
origin: new origins.S3Origin(bucket),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
},
});
// 输出
new cdk.CfnOutput(this, "ApiUrl", { value: api.url });
new cdk.CfnOutput(this, "CloudFrontUrl", { value: distribution.distributionDomainName });
}
}
Step 3:更新现有 Stack 并确认差异
# 部署前确认差异
npx cdk diff
# 让 Claude Code 解释差异
claude -p "
读取 cdk diff 的输出,用中文说明本次变更内容。
特别是安全组和 IAM 策略的变更请详细说明。
$(npx cdk diff 2>&1)
"
Step 4:设计多 Stack 架构
生产级基础设施通过拆分 Stack 来管理。
claude -p "
用 CDK TypeScript 设计以下多 Stack 配置。
【Stack 拆分方案】
- NetworkStack: VPC、子网、安全组
- DatabaseStack: RDS、ElastiCache(依赖 NetworkStack)
- ApplicationStack: ECS、ALB、AutoScaling(依赖 NetworkStack、DatabaseStack)
- MonitoringStack: CloudWatch 仪表板、告警、SNS 通知
包含 Stack 间的依赖关系以及 CfnOutput / Fn.importValue 的使用方法
"
// bin/app.ts
import * as cdk from "aws-cdk-lib";
import { NetworkStack } from "../lib/network-stack";
import { DatabaseStack } from "../lib/database-stack";
import { ApplicationStack } from "../lib/application-stack";
import { MonitoringStack } from "../lib/monitoring-stack";
const app = new cdk.App();
const env = { account: process.env.CDK_ACCOUNT, region: "ap-northeast-1" };
const network = new NetworkStack(app, "NetworkStack", { env });
const database = new DatabaseStack(app, "DatabaseStack", { env, vpc: network.vpc });
const application = new ApplicationStack(app, "ApplicationStack", {
env,
vpc: network.vpc,
database: database.cluster,
});
new MonitoringStack(app, "MonitoringStack", {
env,
alb: application.alb,
database: database.cluster,
});
Step 5:将 CloudFormation/CDK 调试交给 Claude Code
部署失败时的报错也可以让 Claude Code 来解决。
claude -p "
CDK deploy 因以下错误失败。
请说明原因和修复方法:
$(npx cdk deploy 2>&1 | tail -30)
"
常见失败模式:
- ROLLBACK_COMPLETE:上次部署失败导致 Stack 损坏 → 执行
cdk destroy后重新部署 - UPDATE_ROLLBACK_FAILED:与手动变更冲突 → 在 AWS 控制台手动处理
- Resource already exists:与现有资源名称冲突 → 修改资源名称或导入
4 个常见陷阱
1. 用 cdk destroy 绕过删除保护
开发环境中如果不设置 removalPolicy: DESTROY,cdk destroy 后资源会残留。生产环境中设置 RETAIN 防止误删。
2. 忽视 CloudFormation 漂移检测
在 AWS 控制台手动变更资源后,CloudFormation 与实际状态会产生偏差(漂移)。每月在 CloudFormation 控制台执行一次漂移检测。
3. 在模板中直接写入密钥
# 危险:密码残留在模板中
DBPassword: "mysecretpassword"
# 安全:从 Secrets Manager 或 Parameter Store 获取
DBPassword: !Sub "{{resolve:secretsmanager:prod/db-password}}"
4. 忽视 CDK 版本锁定
团队内 package.json 中 CDK 版本不统一会产生差异。提交 package-lock.json 来统一版本。
总结
| 任务 | Claude Code 的贡献 |
|---|---|
| CloudFormation 生成 | 只需描述需求即可得到完整 YAML |
| CDK 实现 | TypeScript 类型安全的基础设施代码 |
| Stack 设计 | 多 Stack 依赖关系架构 |
| 差异说明 | 用中文解释 cdk diff 输出 |
| 调试 | 从错误日志给出原因和修复方法 |
基础设施即代码是大家都知道该做却一直拖着的事情。用 Claude Code,只需说**“我需要这样的 AWS 配置”,模板就能完成**,IaC 的导入门槛大幅降低。
相关文章
参考资料
免费 PDF:5 分钟看懂 Claude Code 速查表
只需留下邮箱,我们就会立即把这份 A4 一页速查表 PDF 发送给你。
我们会严格保护你的个人信息,绝不发送垃圾邮件。
本文作者
Masa
深度使用 Claude Code 的工程师。运营 claudecode-lab.com——一个涵盖 10 种语言、超过 2,000 页内容的科技媒体。
相关文章
Claude Code × Amazon Bedrock 完整指南 | 在AWS上将Claude投入生产环境
使用Claude Code充分利用Amazon Bedrock的完整指南。从IAM认证、流式传输、Lambda集成、RAG实现到成本优化——基于Masa的实际生产实施经验。
Claude Code × AWS CodePipeline/CodeBuild 完全指南 | 自动构建CI/CD流水线
使用Claude Code通过AWS CodePipeline和CodeBuild自动构建CI/CD。包含流水线设计、buildspec.yml生成、测试自动化、CDK基础设施定义的实战代码解说。
Claude Code × AWS CloudWatch 完整指南 | 日志分析·告警设置·仪表盘自动构建
用 Claude Code 提升 AWS CloudWatch 效率。包含日志模式分析、自动告警配置、指标仪表盘构建及故障排查的实战代码解析。