Use Cases (更新: 2026/6/3)

用 Claude Code 审查 AWS CloudFormation 和 CDK:实战 IaC 指南

用Claude Code安全审查AWS CDK与CloudFormation,覆盖IAM、diff、漂移、回滚与护栏。

用 Claude Code 审查 AWS CloudFormation 和 CDK:实战 IaC 指南

在 AWS Console 里点几下很快,但几个月后要解释“为什么生产环境和 staging 不一样”就会很痛苦。CloudFormation 和 AWS CDK 可以把基础设施变成代码,不过 IaC 并不自动等于安全。一个过宽的 IAM policy、一次无意的资源替换、一个忘记关掉的 NAT Gateway,都可能带来安全或成本事故。

我更推荐把 Claude Code 当作 IaC 的起草和审查伙伴,而不是自动部署机器人。它适合生成 CloudFormation/CDK 初稿、解释 cdk diff、检查 IAM 权限扩大、把 CloudFormation 事件整理成回滚清单。最终是否部署,仍然要由人来确认。

给初学者的解释:CloudFormation 是 AWS 官方的模板执行服务;CDK 是用 TypeScript 等语言描述基础设施,再合成为 CloudFormation 模板的开发工具;stack 是一组一起创建、更新、删除的资源;drift(漂移)是实际 AWS 资源和模板不一致。

本文基于 2026 年 6 月 3 日的 AWS 官方文档:

先划清 Claude Code 的职责

安全的做法不是直接说“帮我部署”,而是让 Claude Code 做严格审查。

工作Claude Code 适合做人必须确认
需求整理资源、环境、依赖关系是否真的需要这些资源
模板初稿CloudFormation/CDK 代码命名、删除策略、成本
IAM候选 Action、Resource、Condition是否最小权限
差异审查解释 cdk diff 或 change set删除、替换、权限扩大
故障处理读取事件、提出修复候选回滚方案和生产操作
flowchart LR
  A["写清需求"] --> B["Claude Code 起草 IaC"]
  B --> C["人工检查命名和成本"]
  C --> D["运行 cdk diff 或 change set"]
  D --> E["Claude Code 做风险审查"]
  E --> F["批准后部署"]
  F --> G["记录 drift 和 rollback 检查"]

用例1:把小范围现有资源写成 CloudFormation

不要一开始就把整个生产环境导入。先选一个风险低的切片。下面的模板创建一个私有 S3 bucket,以及一个只读该 bucket 的 Lambda IAM role。因为会创建命名 IAM role,所以需要 CAPABILITY_NAMED_IAM

mkdir cfn-iac-review-demo
cd cfn-iac-review-demo
# 将下面的 YAML 保存为 cfn-safe-iac-demo.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "ClaudeCodeLab safe IaC review demo: private S3 bucket and least-privilege Lambda role"

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - prod
  ProjectName:
    Type: String
    Default: cclab-iac-demo
    AllowedPattern: "^[a-z0-9][a-z0-9-]{2,24}$"

Resources:
  DemoBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: !Sub "${ProjectName}-${Environment}-${AWS::AccountId}-${AWS::Region}"
      VersioningConfiguration:
        Status: Enabled
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      Tags:
        - Key: Project
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment

  DemoReaderRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${ProjectName}-${Environment}-reader-${AWS::Region}"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: ReadOnlyDemoBucket
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: ListOnlyThisBucket
                Effect: Allow
                Action:
                  - s3:ListBucket
                Resource: !GetAtt DemoBucket.Arn
              - Sid: ReadObjectsOnly
                Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "${DemoBucket.Arn}/*"

Outputs:
  BucketName:
    Value: !Ref DemoBucket
  ReaderRoleArn:
    Value: !GetAtt DemoReaderRole.Arn

部署前先让 Claude Code 严格审查:

claude -p "
请把 cfn-safe-iac-demo.yaml 当作 CloudFormation 模板审查。
只用表格指出:
1. 是否可能公开访问
2. IAM Resource 是否过宽
3. 删除或替换时是否会丢数据
4. 是否会产生月度费用
5. 生产 change set 中必须确认什么
"

再创建并查看 change set:

aws cloudformation create-change-set \
  --stack-name cclab-iac-demo-dev \
  --change-set-name review-20260603-001 \
  --template-body file://cfn-safe-iac-demo.yaml \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters ParameterKey=Environment,ParameterValue=dev ParameterKey=ProjectName,ParameterValue=cclab-iac-demo

aws cloudformation describe-change-set \
  --stack-name cclab-iac-demo-dev \
  --change-set-name review-20260603-001

重点看 AddModifyRemoveReplacement。对无状态 demo role 来说替换问题不大,但对 S3、RDS、DynamoDB、KMS key、VPC 子网就是高风险。

用例2:用 CDK TypeScript 写最小安全栈

新项目更适合用 CDK TypeScript。类型和文件结构清楚,Claude Code 生成后也更容易审查。下面示例创建 DynamoDB、S3 和 Lambda,不包含 API Gateway,成本和范围都更小。

mkdir cdk-iac-review-demo
cd cdk-iac-review-demo
npm init -y
npm install aws-cdk-lib constructs
npm install --save-dev aws-cdk typescript ts-node @types/node
mkdir bin lib
{
  "app": "npx ts-node --prefer-ts-exts bin/app.ts"
}
// bin/app.ts
import * as cdk from "aws-cdk-lib";
import { IacReviewDemoStack } from "../lib/iac-review-demo-stack";

const app = new cdk.App();

new IacReviewDemoStack(app, "IacReviewDemoStack", {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION ?? "ap-east-1",
  },
});
// lib/iac-review-demo-stack.ts
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as logs from "aws-cdk-lib/aws-logs";
import * as s3 from "aws-cdk-lib/aws-s3";

export class IacReviewDemoStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const stage = this.node.tryGetContext("stage") ?? "dev";
    const isProd = stage === "prod";

    const table = new dynamodb.Table(this, "AppTable", {
      partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      pointInTimeRecovery: isProd,
      deletionProtection: isProd,
      removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
    });

    const bucket = new s3.Bucket(this, "PrivateAssetsBucket", {
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      enforceSSL: true,
      encryption: s3.BucketEncryption.S3_MANAGED,
      versioned: true,
      removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: !isProd,
    });

    const fn = new lambda.Function(this, "ApiHandler", {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: "index.handler",
      code: lambda.Code.fromInline(`
exports.handler = async () => ({
  statusCode: 200,
  body: JSON.stringify({
    tableName: process.env.TABLE_NAME,
    bucketName: process.env.BUCKET_NAME
  })
});
`),
      environment: {
        TABLE_NAME: table.tableName,
        BUCKET_NAME: bucket.bucketName,
        STAGE: stage,
      },
      timeout: cdk.Duration.seconds(10),
      memorySize: 256,
      logRetention: logs.RetentionDays.ONE_WEEK,
    });

    table.grantReadWriteData(fn);
    bucket.grantPut(fn);

    fn.addToRolePolicy(
      new iam.PolicyStatement({
        sid: "DenyInsecureS3Transport",
        effect: iam.Effect.DENY,
        actions: ["s3:*"],
        resources: [bucket.bucketArn, bucket.arnForObjects("*")],
        conditions: { Bool: { "aws:SecureTransport": "false" } },
      }),
    );

    cdk.Tags.of(this).add("Project", "ClaudeCodeLab");
    cdk.Tags.of(this).add("Stage", stage);

    new cdk.CfnOutput(this, "FunctionName", { value: fn.functionName });
    new cdk.CfnOutput(this, "BucketName", { value: bucket.bucketName });
    new cdk.CfnOutput(this, "TableName", { value: table.tableName });
  }
}

先 review,再 deploy:

npx cdk synth -c stage=dev
npx cdk diff -c stage=dev
claude -p "
审查这个 cdk diff。
只指出删除、替换、IAM 权限扩大、S3 暴露、DynamoDB 成本、Lambda 环境变量泄露。
$(npx cdk diff -c stage=dev 2>&1)
"

autoDeleteObjects: !isProd 在开发环境很方便,但如果进入生产就是严重问题。Claude Code 应该帮助你发现这类环境护栏是否失效。

用例3:把生产 diff 翻译给审批人

CDK 的小改动可能在 CloudFormation 中变成资源替换。让 Claude Code 用审批人能理解的语言总结:

claude -p "
请把下面的 cdk diff 总结给不熟悉 AWS 的产品负责人。
列包含:
- 变更类型
- 目标资源
- 用户影响
- 安全影响
- 成本影响
- 批准前要问的问题

$(npx cdk diff -c stage=prod 2>&1)
"

高风险项通常是 IAM ActionResource、对 0.0.0.0/0 开放的 security group、缺少删除保护、S3 public access、CloudFront/NAT Gateway 增加,以及有状态资源替换。

用例4:标准化回滚和 drift 检查

部署失败后直接在 Console 修,很容易制造 drift。先用事件诊断,再把永久修复回写到 IaC。

aws cloudformation describe-stacks --stack-name cclab-iac-demo-dev
aws cloudformation detect-stack-drift --stack-name cclab-iac-demo-dev
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id YOUR_DETECTION_ID
claude -p "
这个 stack 处于 UPDATE_ROLLBACK_FAILED。
阅读 events,并分开说明可能原因、可以触碰的资源、不能触碰的资源、需要按 AWS 官方文档确认的步骤。
$(aws cloudformation describe-stack-events --stack-name cclab-iac-demo-dev 2>&1)
"

常见坑

IAM 太宽。 不要因为能运行就接受 Action: "*"Resource: "*"。按真实用例收窄 action、ARN 和 condition。

不读 diff 就 deploy。 生产前至少要有 synthdiff、change set。看到 Replacement 时停下来确认。

忽视固定成本。 ALB、NAT Gateway、RDS、OpenSearch、常驻 ECS 在低流量时也会收费。让 Claude Code 列出固定月费资源。

把 Console 手动修改当作永久修复。 事故期间可以手动救火,但之后必须回到 CloudFormation 或 CDK。

明文写 secret。 密码和 API key 不应进入模板和 Git 历史。使用 Secrets Manager 或 SSM Parameter Store,并要求 Claude Code 不输出秘密值。

审查提示词

你是严格的 AWS CloudFormation/CDK 审查者。
请在生产发布前审查这个 IaC diff。

检查:
- IAM Action/Resource/Condition 是否最小权限
- security group 或 S3 是否意外公开
- 有状态资源是否会删除或替换
- 是否新增 ALB、NAT Gateway、RDS、OpenSearch 等固定月费
- 是否可能存在 CloudFormation drift
- 回滚时是否需要手动步骤

输出:
1. 现在必须修的问题
2. 给审批人的问题
3. deploy 前要运行的命令
4. deploy 后要运行的命令

延伸阅读

IAM 审查可继续阅读 Claude Code 与 AWS IAM。计算和 API 层建议搭配 AWS LambdaAWS API GatewayAWS DynamoDB

如果你想把 IaC 审查变成团队流程,ClaudeCodeLab 的实践教材团队培训可以帮助你把这些提示词嵌入 Pull Request 模板和发布检查清单。

总结

Claude Code 与 CloudFormation/CDK 配合得最好时,它不是自动部署者,而是严格的第二审查者。让它起草代码,但在部署前必须解释 IAM、成本、替换、回滚和 drift。实际操作后的结论很明确:让 Claude Code 审查 cdk diff 和 change set,比只让它生成模板更能发现生产风险。

#claude-code #aws #cloudformation #cdk #iac #typescript
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

把 Claude Code 变成真正能带来结果的工作流

先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。