Use Cases (Mis à jour: 02/06/2026)

Claude Code × AWS ECS/Fargate Guide Complet | Automatiser un Déploiement Sûr

Déployez ECS/Fargate avec Claude Code: Docker, ECR, task definitions, logs, IAM et pièges terrain.

Claude Code × AWS ECS/Fargate Guide Complet | Automatiser un Déploiement Sûr

ECS/Fargate est un bon choix pour exécuter des conteneurs sur AWS sans gérer d’instances EC2. La difficulté n’est pas Docker. La difficulté est de relier ECR, les task definitions, les rôles IAM, Secrets Manager, le load balancing, CloudWatch Logs, les health checks et les coûts sans laisser une faille opérationnelle.

Dans ce guide, Claude Code est un assistant d’implémentation, pas un pilote automatique. Une task definition est la fiche de lancement du conteneur, Fargate est le runtime serverless qui l’exécute, l’execution role permet à ECS de tirer l’image, lire les secrets et écrire les logs, et le task role est utilisé par le code applicatif quand il appelle les API AWS.

Lors d’une migration réelle de Masa, le premier échec ne venait pas de Docker mais du health check. L’application mettait environ 40 secondes à démarrer et ECS la testait trop tôt. Claude Code génère les fichiers vite, mais il faut lui donner les contraintes d’exploitation: temps de démarrage, réseau privé, logs, rollback et frontière IAM.

Architecture cible

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

Les exemples utilisent ap-northeast-1, une VPC existante et un target group ALB existant. Pour créer aussi le réseau et l’ALB en IaC, lisez le guide interne Claude Code × AWS CloudFormation/CDK. Pour les permissions, commencez par Claude Code × AWS IAM.

Trois cas d’usage concrets

CasPourquoi Fargate convientPoint de vigilance
API REST SaaSGarder deux tasks ou plus derrière un ALB avec déploiement rollingConcevoir connexions DB et health checks avant
Backend d’administrationDémarrer petit sans patch EC2 ni AMIdesiredCount à 0 rend la première requête lente
Image commune API et batchRéutiliser la même image pour service et run-taskGarder le task role en moindre privilège

Pour une charge courte et événementielle, Claude Code × AWS Lambda sera parfois plus simple. Choisissez Fargate pour du HTTP permanent, des requêtes longues, une forte parité Docker ou un runtime peu adapté à Lambda.

1. API minimale avec health check

Commencez par une application qui fonctionne localement. /health est lu par ECS et par l’ALB; il doit rester léger. Si une lenteur temporaire de base de données renvoie 500, ECS peut remplacer des tasks saines.

{
  "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"]

Vérifiez curl -f http://localhost:3000/health avant ECS. Dans le prompt Claude Code, précisez que l’ALB et ECS utilisent le même chemin, que l’application écoute sur 0.0.0.0 et que startPeriod protège le démarrage.

2. Construire et pousser vers ECR

Ce script crée le repository si nécessaire, se connecte, construit l’image et pousse un tag versionné. Évitez de dépendre uniquement de latest, car rollback et audit deviennent pénibles.

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}"

Le flux ECR officiel utilise get-login-password. En CI, préférez GitHub Actions OIDC et des identifiants AWS temporaires plutôt que des access keys longues stockées dans les secrets du dépôt.

3. Enregistrer la task definition ECS

Les tasks Fargate utilisent le mode réseau awsvpc. Si vous injectez une valeur Secrets Manager, l’execution role a besoin de secretsmanager:GetSecretValue; avec une clé KMS gérée par vous, ajoutez aussi kms:Decrypt. Le task role sert au code applicatif.

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 évite qu’ECS juge le conteneur avant que l’application ait eu le temps de démarrer.

4. Créer le service Fargate

La commande suivante utilise des subnets privées, un security group de task et un target group ALB existants. Le security group de la task doit accepter le port 3000 uniquement depuis le security group de l’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}"

Avec des subnets privées et assignPublicIp=DISABLED, la task doit quand même atteindre ECR, CloudWatch Logs et Secrets Manager. Utilisez NAT Gateway ou des VPC endpoints. NAT est pratique, mais peut devenir le coût principal d’un petit environnement de test.

5. Lire CloudWatch Logs et les événements ECS

Le diagnostic ECS combine souvent les événements du service, les raisons d’arrêt des tasks et les logs applicatifs. Donnez les trois à Claude Code pour une analyse utile.

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}"

Les causes fréquentes sont: pull ECR bloqué, secret refusé, ALB incapable d’atteindre le security group de la task, ou application liée à localhost au lieu de 0.0.0.0.

Prompt d’implémentation pour Claude Code

Construis une implémentation de déploiement AWS ECS/Fargate pour une API Node.js.

Contexte:
- 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: injecter DATABASE_URL depuis Secrets Manager
- Logs: CloudWatch Logs /ecs/myapp, retention 30 days

Livrables:
1. Dockerfile de production
2. Script bash pour pousser vers ECR
3. Script bash pour enregistrer la ECS task definition
4. Script bash pour créer le service Fargate
5. Script bash pour inspecter CloudWatch Logs
6. Explication séparant execution role et task role

Contraintes:
- Pas de pseudocode. Les commandes doivent être exécutables avec AWS CLI après remplissage des variables.
- Ne pas coder les secrets en dur.
- Ne pas exposer la task directement dans une public subnet.
- Terminer par les points de documentation officielle AWS à vérifier.

Vérifications dans la documentation officielle AWS

Pièges concrets

Le premier piège est de mélanger execution role et task role. ECR, logs et lecture de secrets vont dans l’execution role. DynamoDB, S3, SQS et permissions applicatives vont dans le task role.

Le deuxième est un secret dans la mauvaise région. La task ECS, le secret Secrets Manager et la clé KMS doivent être alignés. En multi-région, l’ARN du secret doit être une variable de déploiement par environnement.

Le troisième est le coût. Fargate est facturé à l’usage, mais ALB, NAT Gateway, CloudWatch Logs et stockage ECR comptent aussi. En test, fixez la rétention des logs, arrêtez les services inutilisés et surveillez NAT.

Le quatrième est un health check trop strict. Gardez /health léger et déplacez les vérifications profondes vers /ready ou des smoke tests.

Le cinquième est l’architecture d’image. Si vous construisez ARM64 sur Apple Silicon et que la task est X86_64, le démarrage échouera. Utilisez docker buildx build --platform linux/amd64 ou alignez runtimePlatform.

CTA et prochaine étape

En solo, copiez ces scripts dans une petite API et utilisez la cheatsheet Claude Code gratuite pour améliorer vos prompts. Pour une équipe qui doit concevoir ECS, IAM, CI/CD, observabilité et rollback ensemble, commencez par formation et consultation Claude Code. Pour des prompts et supports de revue réutilisables, consultez les produits ClaudeCodeLab.

Résumé

ECS/Fargate n’est pas seulement un endroit où pousser une image Docker. C’est une conception combinée d’IAM, réseau, secrets, logs, health checks et coûts. Claude Code est le plus utile quand vous lui donnez d’abord les règles opérationnelles, puis demandez des fichiers exécutables.

Après avoir testé ce flux, le plus grand gain venait du prompt, pas du Dockerfile. Demander explicitement la séparation execution role/task role, les commandes CloudWatch Logs et le health check grace period a évité de répéter la même panne. Le premier essai a tout de même révélé une permission de secret manquante, mais avec les événements ECS et les logs, Claude Code a proposé la correction IAM et les étapes de redeploy en une passe.

#claude-code #aws #ecs #fargate #container #devops
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.