Use Cases (Atualizado: 02/06/2026)

Deploy na AWS com Claude Code: CDK, GitHub Actions, IAM, logs e rollback

Publique uma API pequena na AWS com Claude Code, CDK, OIDC, IAM mínimo, logs, rollback e controle de custos.

Deploy na AWS com Claude Code: CDK, GitHub Actions, IAM, logs e rollback

O jeito arriscado de usar Claude Code para deploy na AWS é pedir “crie uma arquitetura AWS” e aceitar a primeira resposta. Deploy pronto para operar não é só diagrama. Ele precisa de IaC executável, IAM com permissões limitadas, gestão de segredos, logs, rollback e limites de custo.

Neste guia vamos implementar um caminho seguro para uma aplicação web pequena ou API: API Gateway + Lambda + AWS CDK + GitHub Actions. CDK é Infrastructure as Code: recursos AWS descritos em código, em vez de cliques manuais no console. IAM é o sistema de permissões que define quem pode fazer cada ação. OIDC permite que o GitHub Actions assuma uma role da AWS com credenciais temporárias, sem guardar AWS keys permanentes.

Claude Code ajuda porque lê o repositório, edita vários arquivos, roda cdk synth e cdk diff, explica erros de deploy e transforma o processo em documentação. Para o produto, use a documentação oficial do Claude Code. Para AWS, consulte AWS CDK NodejsFunction, API Gateway Lambda proxy integration, variáveis de ambiente do Lambda, CloudWatch Logs para Lambda e boas práticas de IAM.

Escolha o alvo AWS antes de codar

Se o alvo ficar vago, Claude Code tende a montar uma solução maior do que o necessário.

OpçãoQuando usarVantagemAtenção
Lambda + API GatewayAPIs pequenas, formulários, webhooks, backends levesPouca administração de servidor e bom começo para baixo tráfegoNão é ideal para tarefas longas, conexões persistentes ou grandes contêineres
ECS/Fargate + ALBAPIs Docker, serviços sempre ativos, API com workersMais liberdade para contêineres e migração de apps existentesExige VPC, ALB, task definitions, scaling e build de imagem
Amplify ou S3 + CloudFrontSites estáticos, SPAs, apps focadas em frontendEntrega rápida via CDN e operação simplesAPI, autenticação e jobs precisam de desenho separado

Aqui escolhemos Lambda + API Gateway porque é um caso comum em consultoria: publicar uma API pequena de forma segura sem criar uma plataforma complexa. Para continuar, veja Claude Code AWS Lambda, Claude Code AWS IAM, Claude Code API Gateway e boas práticas de segurança com Claude Code.

flowchart LR
  User[Usuário] --> Api[API Gateway]
  Api --> Fn[Lambda Node.js API]
  Fn --> Secret[Secrets Manager]
  Fn --> Logs[CloudWatch Logs]
  GitHub[GitHub Actions OIDC] --> CDK[AWS CDK deploy]
  CDK --> Api
  CDK --> Fn

Casos de uso práticos

O primeiro caso é formulário de contato ou captura de leads. O frontend pode continuar no site atual, e apenas o endpoint de envio fica em API Gateway + Lambda. Throttling, API key e CloudWatch Logs ajudam a investigar spam e falhas.

O segundo caso é uma API MVP para SaaS. Comece pequeno, com rotas como /v1/health, /v1/contact e /v1/webhook. Diga ao Claude Code que VPC, RDS, filas e contêineres só devem aparecer quando houver uma necessidade real.

O terceiro caso é webhook interno: alertas no Slack, callbacks de CMS, aprovações ou pequenas ações administrativas. Lambda funciona bem quando cada requisição termina rápido. Se precisar de retry, processamento longo ou fan-out, adicione SQS ou Step Functions de propósito.

O quarto caso é migrar deploy manual para CI/CD. Muitas equipes ainda deployam do notebook ou alteram recursos no console AWS. Claude Code pode levar esse fluxo para CDK e GitHub Actions, mas aprovação de produção, rollback e risco continuam sendo decisões humanas.

Defina regras para Claude Code

Crie um CLAUDE.md na raiz do repositório para evitar que uma API pequena vire uma arquitetura cara.

# AWS deployment rules

- Use AWS CDK v2 and TypeScript.
- Target region: sa-east-1 unless explicitly changed.
- Do not create VPC resources for this small API unless required.
- Prefer API Gateway + Lambda for the first release.
- Runtime secrets must come from AWS Secrets Manager, not plaintext env vars.
- Use IAM grants such as secret.grantRead(handler) instead of wildcard policies.
- Add CloudWatch log retention and reserved concurrency.
- Before deploy, run npm test, npx cdk synth, and npx cdk diff.
- Never paste AWS access keys into files or GitHub Secrets.

Depois peça uma implementação com escopo claro:

Adicione um SmallApiStack CDK v2 neste repositório.
Crie uma API REST no API Gateway e uma Lambda Node.js 20 com /v1/health e /v1/contact.
Leia a configuração de runtime do Secrets Manager: prod/claude-code-demo/api.
Mantenha a role de execução da Lambda com mínimo privilégio e adicione retenção de logs, reserved concurrency e throttling no API Gateway.
O workflow do GitHub Actions deve usar apenas OIDC. Não use AWS keys permanentes.
Depois da edição, rode npm test, npx cdk synth e npx cdk diff, e explique o resultado.

Crie o projeto CDK

Você precisa de Node.js, AWS CLI v2, AWS CDK CLI e um perfil AWS autenticado. Os comandos abaixo são Bash; no Windows, use WSL ou Git Bash.

mkdir claude-code-aws-api
cd claude-code-aws-api
npx cdk init app --language typescript
npm install @aws-sdk/client-secrets-manager
npm install --save-dev esbuild @types/aws-lambda
mkdir -p lambda
aws sts get-caller-identity

Crie a configuração de runtime uma vez. API keys reais, senhas e tokens não devem ir para Git nem para variáveis de ambiente em texto puro.

aws secretsmanager create-secret \
  --name prod/claude-code-demo/api \
  --secret-string '{"supportQueue":"aws-consulting"}' \
  --region sa-east-1

Implemente a Lambda

Crie lambda/handler.ts. O código registra apenas metadados operacionais, sem imprimir corpo completo da requisição nem segredos.

import type {
  APIGatewayProxyEvent,
  APIGatewayProxyResult,
} from "aws-lambda";
import {
  GetSecretValueCommand,
  SecretsManagerClient,
} from "@aws-sdk/client-secrets-manager";

const secrets = new SecretsManagerClient({});
let cachedConfig: Record<string, string> | undefined;

async function loadConfig(): Promise<Record<string, string>> {
  if (cachedConfig) return cachedConfig;

  const secretArn = process.env.SECRET_ARN;
  if (!secretArn) throw new Error("SECRET_ARN is not configured");

  const result = await secrets.send(
    new GetSecretValueCommand({ SecretId: secretArn }),
  );
  cachedConfig = JSON.parse(result.SecretString ?? "{}");
  return cachedConfig;
}

function json(statusCode: number, body: unknown): APIGatewayProxyResult {
  return {
    statusCode,
    headers: {
      "content-type": "application/json",
      "cache-control": "no-store",
    },
    body: JSON.stringify(body),
  };
}

export async function handler(
  event: APIGatewayProxyEvent,
): Promise<APIGatewayProxyResult> {
  try {
    if (event.httpMethod === "GET" && event.path.endsWith("/v1/health")) {
      return json(200, {
        ok: true,
        stage: process.env.STAGE ?? "dev",
      });
    }

    if (event.httpMethod === "POST" && event.path.endsWith("/v1/contact")) {
      const body = JSON.parse(event.body ?? "{}") as {
        email?: string;
        message?: string;
      };

      if (!body.email || !body.message) {
        return json(400, { ok: false, message: "email and message required" });
      }

      const config = await loadConfig();
      const emailDomain = body.email.split("@")[1] ?? "unknown";

      console.log(
        JSON.stringify({
          event: "contact_received",
          emailDomain,
          messageLength: body.message.length,
        }),
      );

      return json(202, {
        ok: true,
        routedTo: config.supportQueue ?? "manual",
      });
    }

    return json(404, { ok: false, message: "not found" });
  } catch (error) {
    console.error("handler_error", error);
    return json(500, { ok: false, message: "internal error" });
  }
}

Implemente o stack CDK

Substitua lib/small-api-stack.ts. Os pontos críticos são appSecret.grantRead(handler), retenção de logs, reserved concurrency, throttling e dataTraceEnabled: false para não registrar corpos de requisição em produção.

import * as cdk from "aws-cdk-lib";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import * as logs from "aws-cdk-lib/aws-logs";
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
import { Construct } from "constructs";
import * as path from "path";

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

    const appSecret = secretsmanager.Secret.fromSecretNameV2(
      this,
      "AppSecret",
      "prod/claude-code-demo/api",
    );

    const handler = new nodejs.NodejsFunction(this, "ApiHandler", {
      functionName: "claude-code-small-api-prod",
      entry: path.join(__dirname, "../lambda/handler.ts"),
      handler: "handler",
      runtime: lambda.Runtime.NODEJS_20_X,
      architecture: lambda.Architecture.ARM_64,
      memorySize: 256,
      timeout: cdk.Duration.seconds(10),
      logRetention: logs.RetentionDays.ONE_MONTH,
      reservedConcurrentExecutions: 20,
      environment: {
        STAGE: "prod",
        SECRET_ARN: appSecret.secretArn,
      },
      bundling: {
        minify: true,
        sourceMap: true,
        externalModules: ["@aws-sdk/*"],
      },
    });

    appSecret.grantRead(handler);

    handler.addToRolePolicy(
      new iam.PolicyStatement({
        actions: ["cloudwatch:PutMetricData"],
        resources: ["*"],
        conditions: {
          StringEquals: {
            "cloudwatch:namespace": "ClaudeCodeLab/SmallApi",
          },
        },
      }),
    );

    const api = new apigateway.RestApi(this, "SmallApi", {
      restApiName: "claude-code-small-api",
      cloudWatchRole: true,
      deployOptions: {
        stageName: "prod",
        metricsEnabled: true,
        loggingLevel: apigateway.MethodLoggingLevel.INFO,
        dataTraceEnabled: false,
        throttlingRateLimit: 20,
        throttlingBurstLimit: 40,
      },
    });

    const v1 = api.root.addResource("v1");
    v1.addResource("health").addMethod(
      "GET",
      new apigateway.LambdaIntegration(handler),
    );

    v1.addResource("contact").addMethod(
      "POST",
      new apigateway.LambdaIntegration(handler),
      { apiKeyRequired: true },
    );

    const apiKey = api.addApiKey("ClientApiKey", {
      apiKeyName: "claude-code-small-api-prod-client",
    });

    const usagePlan = api.addUsagePlan("BasicUsagePlan", {
      throttle: { rateLimit: 10, burstLimit: 20 },
      quota: { limit: 1000, period: apigateway.Period.MONTH },
    });
    usagePlan.addApiKey(apiKey);
    usagePlan.addApiStage({ stage: api.deploymentStage });

    new cdk.CfnOutput(this, "ApiUrl", { value: api.url });
  }
}

Atualize também o arquivo de entrada em bin/.

#!/usr/bin/env node
import * as cdk from "aws-cdk-lib";
import { SmallApiStack } from "../lib/small-api-stack";

const app = new cdk.App();

new SmallApiStack(app, "SmallApiProdStack", {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION ?? "sa-east-1",
  },
});

Revise o diff antes do deploy

O bootstrap do CDK é necessário na primeira vez em uma conta e região.

export AWS_REGION=sa-east-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

npx cdk bootstrap "aws://${AWS_ACCOUNT_ID}/${AWS_REGION}"
npm test
npx cdk synth
npx cdk diff SmallApiProdStack
npx cdk deploy SmallApiProdStack --require-approval never

Peça ao Claude Code para explicar o cdk diff, principalmente mudanças de IAM. Se uma permissão não tiver justificativa clara, ela não deve ir para produção sem revisão humana.

Teste a API e leia logs

Pegue a URL no output do CloudFormation e teste as rotas.

API_URL=$(aws cloudformation describe-stacks \
  --stack-name SmallApiProdStack \
  --query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
  --output text)

curl "${API_URL}v1/health"

KEY_ID=$(aws apigateway get-api-keys \
  --name-query claude-code-small-api-prod-client \
  --query "items[0].id" \
  --output text)

API_KEY=$(aws apigateway get-api-key \
  --api-key "$KEY_ID" \
  --include-value \
  --query "value" \
  --output text)

curl -X POST "${API_URL}v1/contact" \
  -H "content-type: application/json" \
  -H "x-api-key: ${API_KEY}" \
  -d '{"email":"masa@example.com","message":"AWS deployment consultation"}'

Acompanhe os logs da Lambda:

aws logs tail "/aws/lambda/claude-code-small-api-prod" \
  --since 1h \
  --follow

CloudWatch Logs pode demorar alguns minutos. Um pequeno atraso não significa que o deploy falhou.

Deploy com GitHub Actions e OIDC

Não salve AWS Access Keys no GitHub Secrets. Crie um OIDC provider e uma role de deploy na AWS, limitando o trust policy ao repositório e branch corretos.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}

.github/workflows/deploy-aws.yml:

name: deploy-aws-cdk

on:
  push:
    branches: ["main"]
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

concurrency:
  group: prod-aws-cdk
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-cdk-deploy-prod
          aws-region: sa-east-1

      - run: npm ci
      - run: npm test
      - run: npx cdk synth
      - run: npx cdk diff SmallApiProdStack
      - run: npx cdk deploy SmallApiProdStack --require-approval never

A policy da role de deploy depende do modelo de CDK bootstrap, da role de execução do CloudFormation e das regras da organização. Evite AdministratorAccess em produção. O caminho prático é restringir o OIDC, usar permission boundaries quando necessário e reduzir permissões com IAM Access Analyzer.

Adicione guardrails de custo

Uma API serverless pequena também gera custo se entrar em loop, receber spam ou escrever logs demais. O stack inclui throttling, usage plan e reserved concurrency. Adicione AWS Budgets antes da produção.

{
  "BudgetName": "small-api-monthly-guardrail",
  "BudgetLimit": {
    "Amount": "20",
    "Unit": "USD"
  },
  "TimeUnit": "MONTHLY",
  "BudgetType": "COST"
}
[
  {
    "Notification": {
      "NotificationType": "ACTUAL",
      "ComparisonOperator": "GREATER_THAN",
      "Threshold": 80,
      "ThresholdType": "PERCENTAGE"
    },
    "Subscribers": [
      {
        "SubscriptionType": "EMAIL",
        "Address": "owner@example.com"
      }
    ]
  }
]
aws budgets create-budget \
  --account-id "$AWS_ACCOUNT_ID" \
  --budget file://budget.json \
  --notifications-with-subscribers file://notifications-with-subscribers.json

Budgets e notificações podem não aparecer imediatamente. Configure antes do lançamento.

Rollback e falhas comuns

Para o primeiro serviço Lambda + API Gateway, o rollback mais simples costuma ser reverter o commit ruim e redeployar.

git revert <bad-commit-sha>
git push origin main

Depois confira API, eventos do CloudFormation e logs.

curl "${API_URL}v1/health"
aws cloudformation describe-stack-events \
  --stack-name SmallApiProdStack \
  --max-items 20
aws logs tail "/aws/lambda/claude-code-small-api-prod" --since 30m

Três falhas aparecem com frequência: alguém muda recursos no console depois do CDK, segredos aparecem em env vars ou logs, ou API Gateway registra corpos de requisição em produção. O stack usa dataTraceEnabled: false, mas o hábito de revisão continua obrigatório.

Peça uma revisão pré-deploy

Use Claude Code como revisor, exigindo evidência.

Faça uma revisão pré-deploy de AWS.
Verifique:
- Se o CDK diff adiciona wildcards IAM excessivos
- Se Lambda lê segredos apenas do Secrets Manager
- Se API Gateway tem throttling, usage plan e logging
- Se CloudWatch Logs pode expor dados pessoais ou bodies completos
- Se passos de rollback estão documentados
- Se npm test, cdk synth e cdk diff passaram

Retorne uma tabela com severity, file, line e fix.

Claude Code não é o aprovador final de produção. Fronteiras de conta, custo e exceções de segurança continuam com humanos. Ele serve para tornar a revisão repetível.

Resumo

O valor de Claude Code em deploy AWS não é apenas escrever CDK mais rápido. É conectar arquitetura, IaC, CI/CD, IAM, segredos, logs, rollback e custo em um fluxo que a equipe consegue repetir.

Para uma API pequena, Lambda + API Gateway + CDK geralmente basta. Use ECS/Fargate quando realmente precisar de contêiner sempre ativo. Use S3 + CloudFront ou Amplify quando o workload for principalmente frontend estático. O primeiro limite deve ser pequeno, revisável e reversível.

Se sua equipe quer adaptar regras de Claude Code, CDK, GitHub Actions OIDC, IAM mínimo e checks operacionais a um repositório real, agende uma consultoria de Claude Code. Masa pode revisar o repositório e o histórico de deploys AWS para transformar isso em um plano implementável.

Na prática, uma API de captura de leads como esta pode ficar deployável em meio dia a um dia se a conta AWS já estiver pronta. O ponto sensível não é o código Lambda, mas IAM, segredos, rollback e visibilidade de custos. Deixe Claude Code acelerar a implementação; mantenha a responsabilidade humana sobre o risco de produção.

#Claude Code #AWS deployment #CDK #Lambda #GitHub Actions #IAM
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.