Use Cases (Atualizado: 03/06/2026)

Claude Code com AWS CloudFormation e CDK: guia prático de revisão IaC

Revise AWS CDK e CloudFormation com Claude Code: IAM mínimo, diffs, drift, rollback e guardrails práticos.

Claude Code com AWS CloudFormation e CDK: guia prático de revisão IaC

Clicar no console da AWS parece rápido até alguém perguntar por que produção está diferente de staging. CloudFormation e AWS CDK colocam a infraestrutura em código, mas IaC não elimina risco automaticamente. Uma política IAM ampla demais, uma substituição de recurso com estado ou um NAT Gateway esquecido podem virar problema de segurança ou custo.

Eu uso Claude Code como parceiro de rascunho e revisão, não como operador autônomo de deploy. Ele é útil para criar o primeiro CloudFormation/CDK, explicar cdk diff, apontar expansão de permissões e transformar eventos do CloudFormation em checklist de rollback. A aprovação final continua humana.

Para quem está começando: CloudFormation é o serviço AWS que aplica templates. CDK permite escrever infraestrutura em TypeScript e sintetizar CloudFormation. Um stack é a unidade de deploy. Drift significa que o recurso real não bate mais com o código.

Este artigo segue a documentação oficial da AWS verificada em 3 de junho de 2026:

Defina o limite

TrabalhoClaude Code ajuda comHumano aprova
RequisitosRecursos, ambientes, dependênciasSe o recurso é necessário
RascunhoCloudFormation/CDKNomes, remoção, custo
IAMAções e recursos candidatosMenor privilégio real
DiffExplicação de cdk diff ou change setDeletes, replacements, permissões
IncidenteEventos e possíveis correçõesPlano de rollback
flowchart LR
  A["Escrever requisitos"] --> B["Rascunhar IaC com Claude Code"]
  B --> C["Revisar custo e nomes"]
  C --> D["cdk diff ou change set"]
  D --> E["Claude Code revisa riscos"]
  E --> F["Aprovar e deployar"]
  F --> G["Registrar drift e rollback"]

Caso 1: Levar uma parte pequena para CloudFormation

Comece com um recorte de baixo risco. Este template cria um bucket S3 privado e uma role IAM assumível por Lambda que só lê esse bucket. Como cria uma role nomeada, exige CAPABILITY_NAMED_IAM.

mkdir cfn-iac-review-demo
cd cfn-iac-review-demo
# Salve o YAML abaixo como 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

Peça uma revisão rigorosa:

claude -p "
Revise cfn-safe-iac-demo.yaml como template CloudFormation.
Retorne uma tabela com:
1. acesso público acidental
2. escopo de IAM Resource
3. risco de remoção ou substituição
4. possível custo mensal
5. o que verificar em change set de produção
"

Crie e leia o 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

Procure Add, Modify, Remove e Replacement. Em S3, RDS, DynamoDB, KMS ou rede, replacement exige parada e aprovação explícita.

Caso 2: Stack mínimo com CDK TypeScript

Para projetos novos, CDK TypeScript é mais fácil de revisar. Este exemplo cria DynamoDB, S3 e Lambda sem API Gateway para manter o teste pequeno.

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 ?? "sa-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 });
  }
}

Antes de deploy:

npx cdk synth -c stage=dev
npx cdk diff -c stage=dev
claude -p "
Revise este cdk diff.
Marque apenas exclusões, substituições, expansão IAM, exposição S3, custo DynamoDB e vazamento de variáveis Lambda.
$(npx cdk diff -c stage=dev 2>&1)
"

autoDeleteObjects: !isProd é útil em desenvolvimento, mas perigoso em produção. Esse guardrail por ambiente precisa aparecer na revisão.

Caso 3: Explicar diffs de produção

claude -p "
Resuma este cdk diff para uma pessoa de produto que não é especialista AWS.
Use colunas:
- tipo de mudança
- recurso alvo
- impacto para usuários
- impacto de segurança
- impacto de custo
- pergunta antes de aprovar

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

Os riscos recorrentes são IAM Action/Resource, security groups abertos para 0.0.0.0/0, falta de deletion protection, S3 público, CloudFront/NAT Gateway novo e substituição de recurso com estado.

Caso 4: Rollback e drift

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 "
Este stack está em UPDATE_ROLLBACK_FAILED.
Leia os eventos e separe causas prováveis, recursos seguros para tocar, recursos que não devem ser tocados e passos a verificar na documentação AWS.
$(aws cloudformation describe-stack-events --stack-name cclab-iac-demo-dev 2>&1)
"

Armadilhas comuns

IAM amplo demais. Não aceite Action: "*" ou Resource: "*" só porque funciona. Limite actions, ARNs e conditions ao caso real.

Deploy sem ler diff. Produção precisa de synth, diff e change set. Replacement exige revisão.

Custos fixos ignorados. ALB, NAT Gateway, RDS, OpenSearch e ECS sempre ligado geram custo mesmo com pouco tráfego.

Mudança manual como solução permanente. Console pode ajudar em incidente, mas a correção final volta para CloudFormation ou CDK.

Secrets no código. Use Secrets Manager ou SSM Parameter Store e peça ao Claude Code para não imprimir valores secretos.

Prompt de revisão

Você é um revisor rigoroso de AWS CloudFormation/CDK.
Revise este diff de IaC antes de produção.

Verifique:
- IAM Action/Resource/Condition com menor privilégio
- exposição acidental por security groups ou S3
- exclusão ou substituição de recursos com estado
- novo custo fixo como ALB, NAT Gateway, RDS ou OpenSearch
- possível CloudFormation drift
- recursos que exigem rollback manual

Saída:
1. problemas para corrigir agora
2. perguntas para aprovação
3. comandos antes do deploy
4. comandos depois do deploy

Continue estudando

Para IAM, leia Claude Code e AWS IAM. Para execução e dados, combine com AWS Lambda, AWS API Gateway e AWS DynamoDB.

ClaudeCodeLab oferece produtos práticos e treinamento para equipes para transformar estes prompts em templates de Pull Request e checklists de release.

Resumo

Claude Code funciona melhor com CloudFormation/CDK como um segundo revisor rigoroso. Deixe-o escrever rascunhos, mas exija explicações sobre IAM, custo, substituição, rollback e drift antes do deploy. Na prática, revisar cdk diff e change sets com Claude Code encontra mais riscos de produção do que apenas gerar templates.

#claude-code #aws #cloudformation #cdk #iac #typescript
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.