Use Cases

Claude Code × AWS ECS/Fargate Guide Complet | Automatiser les Déploiements de Conteneurs

Automatisez les déploiements AWS ECS/Fargate avec Claude Code. Des définitions de tâches à la configuration des services, en passant par les déploiements Blue/Green et l'infrastructure CDK — basé sur l'expérience terrain de Masa.

« Je veux exécuter des conteneurs sur AWS, mais la configuration d’ECS est beaucoup trop complexe » — c’est le mur que beaucoup de développeurs rencontrent en premier. Définitions de tâches, services, clusters, load balancers, auto scaling… il y a tellement de paramètres qu’on ne sait pas par où commencer.

Je construis des environnements de conteneurs serverless avec ECS/Fargate dans mon travail, et depuis que j’utilise Claude Code pour décrire mon architecture et générer tout, des définitions de tâches jusqu’au code CDK, les déploiements sont devenus beaucoup plus simples. Cet article explique les étapes pratiques.


Fondamentaux d’ECS/Fargate en 3 Minutes

Cluster :          La "boîte" où s'exécutent les conteneurs ECS
Définition de tâche : Spécification du conteneur (image, CPU, mémoire, variables d'env)
Service :          Définit combien de tâches exécuter (inclut l'auto scaling)
Fargate :          Moteur d'exécution de conteneurs serverless — sans gestion de serveur

Contrairement à EC2, Fargate ne nécessite ni provisionnement ni gestion des patches du serveur. Vous pouvez vous concentrer entièrement sur la configuration du conteneur.


Étape 1 : Générer Automatiquement une Définition de Tâche

claude -p "
Génère une définition de tâche ECS en JSON avec les exigences suivantes :

- App : API Node.js (port 3000)
- CPU : 512 (0.5 vCPU)
- Mémoire : 1024 Mo
- Variables d'environnement : DATABASE_URL (récupérée depuis Secrets Manager), NODE_ENV=production
- Journalisation : CloudWatch Logs (groupe de logs /ecs/myapp)
- Health check : endpoint /health, intervalle de 30 secondes
- Image du conteneur : 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
- Rôle d'exécution : ecsTaskExecutionRole
- Rôle de tâche : myapp-task-role (accès à DynamoDB et S3)
"

Définition de tâche générée :

{
  "family": "myapp-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789:role/myapp-task-role",
  "containerDefinitions": [
    {
      "name": "myapp",
      "image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest",
      "portMappings": [{ "containerPort": 3000, "protocol": "tcp" }],
      "environment": [{ "name": "NODE_ENV", "value": "production" }],
      "secrets": [
        {
          "name": "DATABASE_URL",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789:secret:prod/database-url"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/myapp",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      }
    }
  ]
}

Étape 2 : Construire l’Infrastructure ECS/Fargate avec CDK

Au-delà de la définition de tâche, nous allons générer le cluster, le service et l’ALB d’un seul coup avec CDK.

claude -p "
Implémente l'environnement ECS/Fargate suivant en CDK TypeScript dans lib/ecs-stack.ts :

- VPC : Importer un VPC existant (récupérer vpcId depuis la variable d'environnement)
- Cluster ECS : Fargate uniquement
- Définition de tâche : Mêmes specs que celles générées ci-dessus
- ALB : HTTPS (récupérer l'ARN du certificat ACM depuis la variable d'environnement), HTTP redirige avec 301
- Service : Auto scaling avec minimum 2, maximum 10 tâches
  - Scale out à 70% d'utilisation CPU
  - Scaling par suivi de cible
- Support du déploiement Blue/Green (intégration CodeDeploy)
- Afficher l'état du service dans un tableau de bord CloudWatch
"
// lib/ecs-stack.ts
import * as cdk from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as ecs from "aws-cdk-lib/aws-ecs";
import * as ecsp from "aws-cdk-lib/aws-ecs-patterns";
import * as acm from "aws-cdk-lib/aws-certificatemanager";

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

    // Importer le VPC existant
    const vpc = ec2.Vpc.fromLookup(this, "Vpc", {
      vpcId: process.env.VPC_ID!,
    });

    // Cluster ECS
    const cluster = new ecs.Cluster(this, "Cluster", {
      vpc,
      clusterName: "myapp-cluster",
      containerInsights: true,  // Activer CloudWatch Container Insights
    });

    // Certificat ACM
    const certificate = acm.Certificate.fromCertificateArn(
      this, "Certificate",
      process.env.CERTIFICATE_ARN!
    );

    // Définition de tâche
    const taskDef = new ecs.FargateTaskDefinition(this, "TaskDef", {
      cpu: 512,
      memoryLimitMiB: 1024,
    });

    const container = taskDef.addContainer("app", {
      image: ecs.ContainerImage.fromEcrRepository(
        ecr.Repository.fromRepositoryName(this, "Repo", "myapp")
      ),
      environment: { NODE_ENV: "production" },
      logging: ecs.LogDrivers.awsLogs({ streamPrefix: "ecs" }),
      healthCheck: {
        command: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
        interval: cdk.Duration.seconds(30),
        timeout: cdk.Duration.seconds(5),
        retries: 3,
        startPeriod: cdk.Duration.seconds(60),
      },
    });
    container.addPortMappings({ containerPort: 3000 });

    // ALB + Service Fargate (concis avec des patterns)
    const service = new ecsp.ApplicationLoadBalancedFargateService(
      this, "Service", {
        cluster,
        taskDefinition: taskDef,
        desiredCount: 2,
        certificate,
        redirectHTTP: true,
        publicLoadBalancer: true,
      }
    );

    // Configuration de l'auto scaling
    const scaling = service.service.autoScaleTaskCount({
      minCapacity: 2,
      maxCapacity: 10,
    });
    scaling.scaleOnCpuUtilization("CpuScaling", {
      targetUtilizationPercent: 70,
      scaleInCooldown: cdk.Duration.seconds(60),
      scaleOutCooldown: cdk.Duration.seconds(60),
    });

    // Sortie
    new cdk.CfnOutput(this, "LoadBalancerDns", {
      value: service.loadBalancer.loadBalancerDnsName,
    });
  }
}

Étape 3 : Construire un Pipeline CI/CD avec GitHub Actions

claude -p "
Crée le pipeline CI/CD suivant avec GitHub Actions :

1. Déclencheur sur push vers la branche main
2. Construire l'image Docker et la pousser vers ECR
3. Mettre à jour le tag d'image dans la définition de tâche ECS avec le nouveau SHA
4. Déployer la nouvelle définition de tâche vers le service ECS
5. Notifier Slack lors du déploiement réussi

Environnement : ap-northeast-1, nom du dépôt ECR : myapp
"
name: Deploy to ECS

on:
  push:
    branches: [main]

env:
  AWS_REGION: ap-northeast-1
  ECR_REPOSITORY: myapp
  ECS_CLUSTER: myapp-cluster
  ECS_SERVICE: myapp-service
  CONTAINER_NAME: app

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

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build, tag, and push image to ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

      - name: Download task definition
        run: |
          aws ecs describe-task-definition --task-definition myapp-task \
            --query taskDefinition > task-definition.json

      - name: Update ECS task definition with new image
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.CONTAINER_NAME }}
          image: ${{ steps.build-image.outputs.image }}

      - name: Deploy to ECS
        uses: aws-actions/amazon-ecs-deploy-task-definition@v1
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          wait-for-service-stability: true

      - name: Notify Slack on success
        if: success()
        uses: slackapi/slack-github-action@v1
        with:
          webhook: ${{ secrets.SLACK_WEBHOOK }}
          payload: |
            {"text": "✅ Deployed to ECS: ${{ github.sha }}"}

Étape 4 : Configurer le Déploiement Blue/Green

claude -p "
Génère du code CDK et un fichier AppSpec pour configurer le déploiement Blue/Green (CodeDeploy) pour un service ECS.
Condition de rollback : rollback automatique si une alarme CloudWatch se déclenche dans les 5 minutes suivant le déploiement.
"
# appspec.yaml (pour CodeDeploy)
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: <TASK_DEFINITION>
        LoadBalancerInfo:
          ContainerName: app
          ContainerPort: 3000
        PlatformVersion: LATEST
Hooks:
  - BeforeAllowTraffic: "arn:aws:lambda:ap-northeast-1:123456789:function:health-check"
  - AfterAllowTraffic: "arn:aws:lambda:ap-northeast-1:123456789:function:smoke-test"

Les 5 Pièges à Éviter

1. Oublier startPeriod dans le health check

Les conteneurs Fargate exécutent des health checks immédiatement au démarrage, mais si votre application est lente à démarrer, elle devient instantanément UNHEALTHY. Définissez startPeriod: 60 (secondes) pour laisser à votre app le temps de s’initialiser.

2. Confondre le rôle de tâche et le rôle d’exécution

executionRole (ecsTaskExecutionRole) : Permissions nécessaires pour démarrer le conteneur
  → Télécharger l'image depuis ECR, écrire dans CloudWatch Logs

taskRole (myapp-task-role) : Permissions utilisées par l'application
  → Accès à DynamoDB, S3, SQS, etc.

Il est très facile d’ajouter des permissions au mauvais rôle.

3. Configuration du groupe de sécurité en mode réseau awsvpc

Fargate nécessite obligatoirement le mode réseau awsvpc. Si vous oubliez de restreindre le groupe de sécurité du conteneur pour n’autoriser que le trafic depuis l’ALB, le conteneur sera directement exposé à internet.

4. Le rôle d’exécution est nécessaire pour récupérer depuis Secrets Manager

Pour récupérer des valeurs de Secrets Manager via secrets, le executionRole doit avoir la permission secretsmanager:GetSecretValue. L’absence de cette permission est une raison très courante pour laquelle les conteneurs ne démarrent pas.

5. Le problème de desired_count: 0 lors du déploiement

Un service avec un minimum de 0 en auto scaling peut éteindre tous les conteneurs la nuit, causant des démarrages lents le matin. Définissez le minimum à au moins 2 en production.


Récapitulatif

TâcheContribution de Claude Code
Génération de définition de tâcheJSON complet à partir des exigences seules
Implémentation CDKCluster, service, ALB, auto scaling générés ensemble
Configuration CI/CDGénération du workflow GitHub Actions
Déploiement Blue/GreenAppSpec et configuration CodeDeploy générés automatiquement
Résolution de problèmesIdentifie la cause et les corrections depuis les logs d’erreur

ECS a de nombreux éléments de configuration, mais en disant à Claude Code « je veux ce type de setup », vous obtenez une configuration complète suivant les meilleures pratiques. Commencer par CDK est l’approche la plus simple et la plus recommandée.

Articles Connexes

Références

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

Passez votre flux Claude Code au niveau supérieur

50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.

Gratuit

PDF gratuit : aide-mémoire Claude Code en 5 minutes

Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.

Nous traitons vos données avec soin et n'envoyons jamais de spam.

Masa

À propos de l'auteur

Masa

Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.