Use Cases (Atualizado: 02/06/2026)

Claude Code × AWS ECS/Fargate Guia Completo | Automatize Deployments Seguros

Implante ECS/Fargate com Claude Code: Docker, ECR, task definitions, logs, IAM e armadilhas reais.

Claude Code × AWS ECS/Fargate Guia Completo | Automatize Deployments Seguros

ECS/Fargate é uma boa escolha para executar containers na AWS sem administrar instâncias EC2. A parte difícil não é o Dockerfile. A parte difícil é conectar ECR, task definitions, roles IAM, Secrets Manager, load balancing, CloudWatch Logs, health checks e controle de custos sem deixar uma lacuna de produção.

Neste guia, Claude Code é um assistente de implementação, não um piloto automático. A task definition é a especificação de inicialização do container, Fargate é o runtime serverless que o executa, a execution role permite que o ECS baixe imagens, leia secrets e escreva logs, e a task role é a permissão usada pelo código da aplicação ao chamar APIs da AWS.

Em uma migração real de Masa, a primeira falha não foi Docker, mas health check. A aplicação precisava de cerca de 40 segundos para iniciar e o ECS começou a checar cedo demais. Claude Code gera arquivos rápido, mas você precisa informar tempo de inicialização, rede privada, logs, rollback e quais permissões pertencem a cada role.

Arquitetura alvo

Developer
  |
  | docker build / push
  v
Amazon ECR ----> Amazon ECS Service on AWS Fargate
                       |
                       | pulls secrets / writes logs
                       v
Secrets Manager     CloudWatch Logs
                       ^
                       |
Application Load Balancer -> /health -> Node.js container

Os exemplos usam ap-northeast-1, uma VPC existente e um target group de ALB existente. Se você quiser criar rede e ALB com IaC, leia também o guia interno Claude Code × AWS CloudFormation/CDK. Para o modelo de permissões, revise Claude Code × AWS IAM antes de tocar produção.

Três casos de uso práticos

CasoPor que Fargate encaixaAtenção
API REST SaaSMantém duas ou mais tasks atrás de ALB com deploy rollingPlanejar conexões de DB e health checks antes
Backend administrativoComeça pequeno sem patches EC2 ou AMIsdesiredCount em 0 deixa a primeira requisição lenta
Imagem comum para API e batchA mesma imagem serve para service e run-taskManter a task role com menor privilégio

Se a carga é curta e orientada a eventos, Claude Code × AWS Lambda pode ser mais simples. Escolha Fargate para HTTP sempre ativo, requisições mais longas, paridade Docker ou runtime que não encaixa bem em Lambda.

1. API mínima com health check

Comece com uma aplicação que funciona localmente. /health será lido por ECS e ALB, então mantenha leve. Se uma lentidão temporária do banco retornar 500, ECS pode substituir tasks saudáveis.

{
  "scripts": {
    "start": "node src/server.js"
  },
  "dependencies": {
    "express": "^4.19.2"
  }
}
// src/server.js
const express = require("express");

const app = express();
const port = Number(process.env.PORT || 3000);

app.get("/health", (_req, res) => {
  res.status(200).json({
    ok: true,
    service: "myapp",
    time: new Date().toISOString(),
  });
});

app.get("/", (_req, res) => {
  res.json({ message: "Hello from ECS Fargate" });
});

app.listen(port, "0.0.0.0", () => {
  console.log(`myapp listening on ${port}`);
});
# Dockerfile
FROM node:22-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

COPY src ./src
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000

CMD ["node", "src/server.js"]

Verifique curl -f http://localhost:3000/health antes de ir para ECS. No prompt para Claude Code, diga que ALB e ECS usam a mesma rota, que a aplicação escuta em 0.0.0.0 e que startPeriod protege a inicialização.

2. Build e push para ECR

Este script cria o repositório se necessário, faz login, constrói a imagem e envia uma tag versionada. Evite depender apenas de latest, porque rollback e auditoria ficam difíceis.

set -euo pipefail

export AWS_REGION="ap-northeast-1"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export ECR_REPOSITORY="myapp"
export IMAGE_TAG="$(git rev-parse --short HEAD 2>/dev/null || date +%Y%m%d%H%M%S)"
export IMAGE_URI="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}"

aws ecr describe-repositories \
  --repository-names "${ECR_REPOSITORY}" \
  --region "${AWS_REGION}" >/dev/null 2>&1 || \
aws ecr create-repository \
  --repository-name "${ECR_REPOSITORY}" \
  --image-scanning-configuration scanOnPush=true \
  --region "${AWS_REGION}"

aws ecr get-login-password --region "${AWS_REGION}" | \
  docker login --username AWS --password-stdin \
  "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"

docker build -t "${IMAGE_URI}" .
docker push "${IMAGE_URI}"

echo "Pushed ${IMAGE_URI}"

O fluxo oficial do ECR usa get-login-password. Em CI, prefira GitHub Actions OIDC e credenciais AWS temporárias, em vez de access keys longas armazenadas em secrets do repositório.

3. Registrar a task definition do ECS

Tasks Fargate usam rede awsvpc. Ao injetar valores do Secrets Manager, a execution role precisa de secretsmanager:GetSecretValue; se o secret usa KMS key gerenciada por você, adicione kms:Decrypt. A task role é para o código da aplicação.

set -euo pipefail

export AWS_REGION="ap-northeast-1"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export IMAGE_URI="${IMAGE_URI:?Run the ECR push script first}"
export EXECUTION_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/ecsTaskExecutionRole"
export TASK_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/myapp-task-role"
export SECRET_ARN="arn:aws:secretsmanager:${AWS_REGION}:${AWS_ACCOUNT_ID}:secret:prod/myapp/DATABASE_URL"

aws logs create-log-group --log-group-name /ecs/myapp --region "${AWS_REGION}" 2>/dev/null || true
aws logs put-retention-policy --log-group-name /ecs/myapp --retention-in-days 30 --region "${AWS_REGION}"

cat > ecs-task-definition.json <<EOF
{
  "family": "myapp-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "${EXECUTION_ROLE_ARN}",
  "taskRoleArn": "${TASK_ROLE_ARN}",
  "runtimePlatform": {
    "cpuArchitecture": "X86_64",
    "operatingSystemFamily": "LINUX"
  },
  "containerDefinitions": [
    {
      "name": "app",
      "image": "${IMAGE_URI}",
      "essential": true,
      "portMappings": [
        { "containerPort": 3000, "hostPort": 3000, "protocol": "tcp" }
      ],
      "environment": [
        { "name": "NODE_ENV", "value": "production" },
        { "name": "PORT", "value": "3000" }
      ],
      "secrets": [
        { "name": "DATABASE_URL", "valueFrom": "${SECRET_ARN}" }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/myapp",
          "awslogs-region": "${AWS_REGION}",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "wget -qO- http://localhost:3000/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      }
    }
  ]
}
EOF

aws ecs register-task-definition \
  --cli-input-json file://ecs-task-definition.json \
  --region "${AWS_REGION}"

startPeriod evita que o ECS julgue o container antes de a aplicação ter tempo razoável para iniciar.

4. Criar o serviço Fargate

O comando a seguir usa private subnets, task security group e ALB target group existentes. O security group da task deve aceitar porta 3000 apenas do security group do ALB.

set -euo pipefail

export AWS_REGION="ap-northeast-1"
export CLUSTER_NAME="myapp-cluster"
export SERVICE_NAME="myapp-service"
export TASK_FAMILY="myapp-task"
export SUBNET_1="subnet-xxxxxxxx"
export SUBNET_2="subnet-yyyyyyyy"
export TASK_SECURITY_GROUP="sg-xxxxxxxx"
export TARGET_GROUP_ARN="arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/myapp/abc123"

aws ecs create-cluster \
  --cluster-name "${CLUSTER_NAME}" \
  --region "${AWS_REGION}" >/dev/null

aws ecs create-service \
  --cluster "${CLUSTER_NAME}" \
  --service-name "${SERVICE_NAME}" \
  --task-definition "${TASK_FAMILY}" \
  --desired-count 2 \
  --launch-type FARGATE \
  --platform-version LATEST \
  --health-check-grace-period-seconds 90 \
  --network-configuration "awsvpcConfiguration={subnets=[${SUBNET_1},${SUBNET_2}],securityGroups=[${TASK_SECURITY_GROUP}],assignPublicIp=DISABLED}" \
  --load-balancers "targetGroupArn=${TARGET_GROUP_ARN},containerName=app,containerPort=3000" \
  --region "${AWS_REGION}"

aws ecs wait services-stable \
  --cluster "${CLUSTER_NAME}" \
  --services "${SERVICE_NAME}" \
  --region "${AWS_REGION}"

Em private subnets com assignPublicIp=DISABLED, a task ainda precisa de caminho para ECR, CloudWatch Logs e Secrets Manager. Use NAT Gateway ou VPC endpoints. NAT é prático, mas pode dominar o custo de um ambiente pequeno.

5. Ver CloudWatch Logs e eventos ECS

Diagnóstico de ECS normalmente exige eventos do service, razões de tasks paradas e logs da aplicação. Envie os três para Claude Code ao pedir investigação.

export AWS_REGION="ap-northeast-1"
export CLUSTER_NAME="myapp-cluster"
export SERVICE_NAME="myapp-service"

aws ecs describe-services \
  --cluster "${CLUSTER_NAME}" \
  --services "${SERVICE_NAME}" \
  --query "services[0].events[0:5].[createdAt,message]" \
  --output table \
  --region "${AWS_REGION}"

aws ecs list-tasks \
  --cluster "${CLUSTER_NAME}" \
  --service-name "${SERVICE_NAME}" \
  --desired-status STOPPED \
  --region "${AWS_REGION}"

aws logs tail /ecs/myapp \
  --follow \
  --since 10m \
  --region "${AWS_REGION}"

Falhas comuns: pull do ECR bloqueado, acesso negado ao secret, ALB não alcança o security group da task ou a app escuta em localhost em vez de 0.0.0.0.

Template de pedido para Claude Code

Crie uma implementação de deploy AWS ECS/Fargate para uma API Node.js.

Contexto:
- Region: ap-northeast-1
- ECR repository: myapp
- Container port: 3000
- Health endpoint: /health
- ECS launch type: FARGATE
- Network mode: awsvpc
- Desired count: 2
- Task CPU/memory: 512 / 1024
- Secret: injetar DATABASE_URL pelo Secrets Manager
- Logs: CloudWatch Logs /ecs/myapp, retention 30 days

Entregáveis:
1. Dockerfile de produção
2. Bash script para push no ECR
3. Bash script para registrar a ECS task definition
4. Bash script para criar o Fargate service
5. Bash script para inspecionar CloudWatch Logs
6. Explicação separando execution role e task role

Restrições:
- Sem pseudocódigo. Os comandos devem rodar com AWS CLI depois de preencher variáveis.
- Não hardcodear valores de secret.
- Não expor a task diretamente em public subnet.
- Encerrar com pontos da documentação oficial AWS que devo verificar.

Pontos para conferir na documentação oficial AWS

Armadilhas concretas

A primeira é misturar execution role e task role. ECR, logs e leitura de secrets ficam na execution role. DynamoDB, S3, SQS e permissões da app ficam na task role.

A segunda é secret em região errada. ECS task, Secrets Manager secret e KMS key precisam estar alinhados. Em multi-região, o ARN do secret deve ser variável de deploy por ambiente.

A terceira é custo. Fargate é por uso, mas ALB, NAT Gateway, CloudWatch Logs e armazenamento ECR também contam. Em testes, defina retenção de logs, pare services não usados e revise NAT.

A quarta é health check rígido demais. Mantenha /health leve e mova verificações profundas para /ready ou smoke tests.

A quinta é arquitetura da imagem. Se você cria ARM64 em Apple Silicon e a task está como X86_64, a inicialização falha. Use docker buildx build --platform linux/amd64 ou alinhe runtimePlatform.

CTA e próximo passo

Quem trabalha sozinho pode copiar estes scripts para uma API pequena e usar a cheatsheet gratuita de Claude Code para melhorar prompts. Equipes que precisam desenhar ECS, IAM, CI/CD, observabilidade e rollback juntas podem começar por treinamento e consultoria Claude Code. Para prompts e materiais de review reutilizáveis, veja os produtos ClaudeCodeLab.

Resumo

ECS/Fargate não é apenas um lugar para subir imagens Docker. É um desenho conjunto de IAM, rede, secrets, logs, health checks e custos. Claude Code funciona melhor quando recebe primeiro as regras operacionais e depois gera arquivos executáveis.

Ao testar este fluxo, a maior melhoria veio do prompt, não do Dockerfile. Pedir explicitamente a separação entre execution role e task role, comandos de CloudWatch Logs e health check grace period evitou repetir a mesma falha. A primeira execução ainda revelou uma permissão ausente para secret, mas ao enviar eventos ECS e logs para Claude Code, ele retornou a correção IAM e os passos de redeploy em uma rodada.

#claude-code #aws #ecs #fargate #container #devops
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.