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

Déployer sur AWS avec Claude Code : CDK, GitHub Actions, IAM, logs et rollback

Déployez une petite API AWS avec Claude Code, CDK, OIDC, IAM minimal, logs, rollback et garde-fous de coût.

Déployer sur AWS avec Claude Code : CDK, GitHub Actions, IAM, logs et rollback

Le mauvais usage de Claude Code pour un déploiement AWS consiste à demander “fais-moi une architecture AWS” puis à accepter le résultat sans preuve d’exécution. Une architecture exploitable n’est pas seulement un schéma. Elle inclut du code d’infrastructure qui tourne, des permissions IAM limitées, une gestion des secrets, des logs, un rollback et des garde-fous de coût.

Dans ce guide, nous implémentons une voie sûre pour une petite application web ou API : API Gateway + Lambda + AWS CDK + GitHub Actions. CDK signifie Infrastructure as Code : les ressources AWS sont décrites dans du code au lieu d’être créées à la main dans la console. IAM est le système qui définit qui peut faire quoi. OIDC permet à GitHub Actions d’assumer un rôle AWS avec des identifiants temporaires, sans stocker de clé AWS longue durée.

Claude Code aide parce qu’il lit le dépôt, modifie plusieurs fichiers, lance cdk synth et cdk diff, explique les erreurs de déploiement et documente le flux. Pour le produit, consultez la documentation officielle Claude Code. Pour AWS, appuyez-vous sur les références officielles : AWS CDK NodejsFunction, API Gateway Lambda proxy integration, variables d’environnement Lambda, CloudWatch Logs pour Lambda et bonnes pratiques IAM.

Choisir la cible AWS avant de coder

Si la cible reste vague, Claude Code risque de proposer trop de services. Commencez par nommer la forme de charge.

OptionUsage adaptéPoint fortAttention
Lambda + API GatewayPetites API, formulaires, webhooks, backends légersPeu d’administration serveur, bon départ pour faible traficPas idéal pour traitements longs, connexions persistantes ou gros conteneurs
ECS/Fargate + ALBAPI Docker, services toujours actifs, API avec workersLiberté du conteneur, migration naturelle d’apps existantesVPC, ALB, task definitions, scaling et images à gérer
Amplify ou S3 + CloudFrontSites statiques, SPA, apps centrées frontendDiffusion CDN rapide et opération simpleAPI, auth et jobs backend à concevoir séparément

Ici, nous choisissons Lambda + API Gateway, car c’est le cas le plus fréquent : publier une petite API sans construire une plateforme complète dès le départ. Pour aller plus loin, lisez Claude Code AWS Lambda, Claude Code AWS IAM, Claude Code API Gateway et bonnes pratiques sécurité Claude Code.

flowchart LR
  User[Utilisateur] --> 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

Cas d’usage concrets

Premier cas : un formulaire de contact ou de génération de leads. Le frontend reste sur le site existant, et seul l’endpoint de soumission passe sur API Gateway + Lambda. Le throttling, une API key et CloudWatch Logs rendent le spam et les incidents plus faciles à analyser.

Deuxième cas : une API MVP pour un SaaS. Démarrez avec des routes limitées comme /v1/health, /v1/contact et /v1/webhook. Dites clairement à Claude Code de ne pas créer de VPC, RDS, queue ou conteneur tant que le besoin n’existe pas.

Troisième cas : un webhook interne. Alertes Slack, callbacks de CMS, validation d’approbation, petites opérations d’administration : Lambda convient si chaque requête se termine vite. Si vous avez besoin de retry, de traitement long ou de fan-out, ajoutez SQS ou Step Functions volontairement.

Quatrième cas : migrer un déploiement manuel vers CI/CD. Beaucoup d’équipes déploient encore depuis un ordinateur local ou en cliquant dans la console AWS. Claude Code peut transformer ces actions en CDK et GitHub Actions, mais les règles d’approbation, de production et de rollback restent des décisions humaines.

Donner des règles de déploiement à Claude Code

Créez un CLAUDE.md à la racine du dépôt. Il sert de contrat pour éviter qu’une petite API devienne une architecture trop chère.

# AWS deployment rules

- Use AWS CDK v2 and TypeScript.
- Target region: eu-west-3 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.

Puis demandez une implémentation bornée :

Ajoute un SmallApiStack CDK v2 dans ce dépôt.
Crée une API REST API Gateway et une Lambda Node.js 20 avec /v1/health et /v1/contact.
Lis la configuration runtime depuis Secrets Manager : prod/claude-code-demo/api.
Garde le rôle d'exécution Lambda en moindre privilège, ajoute la rétention des logs, reserved concurrency et throttling API Gateway.
Le workflow GitHub Actions doit utiliser uniquement OIDC. N'utilise pas de clés AWS longue durée.
Après modification, exécute npm test, npx cdk synth et npx cdk diff, puis explique le résultat.

Créer le projet CDK

Il faut Node.js, AWS CLI v2, AWS CDK CLI et un profil AWS authentifié. Les commandes ci-dessous sont en Bash ; sous Windows, utilisez 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

Créez une fois la configuration runtime. Les vraies clés API, mots de passe et tokens ne doivent pas être committés ni placés en variables d’environnement en clair.

aws secretsmanager create-secret \
  --name prod/claude-code-demo/api \
  --secret-string '{"supportQueue":"aws-consulting"}' \
  --region eu-west-3

Implémenter la Lambda

Créez lambda/handler.ts. Le code journalise uniquement des métadonnées opérationnelles, pas le corps complet ni les secrets.

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

Implémenter le stack CDK

Remplacez lib/small-api-stack.ts. Les points importants sont appSecret.grantRead(handler), la rétention des logs, le reserved concurrency, le throttling et dataTraceEnabled: false pour éviter d’écrire les corps de requête en production.

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 });
  }
}

Mettez aussi à jour le fichier d’entrée dans 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 ?? "eu-west-3",
  },
});

Vérifier le diff avant le déploiement

CDK bootstrap est nécessaire la première fois dans un compte et une région.

export AWS_REGION=eu-west-3
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

Demandez à Claude Code d’expliquer le cdk diff, surtout les changements IAM. S’il ne peut pas justifier une permission, elle ne doit pas partir en production sans revue.

Tester l’API et lire les logs

Récupérez l’URL depuis CloudFormation, puis appelez les routes.

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

Suivez les logs Lambda :

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

CloudWatch Logs peut prendre quelques minutes. Un court délai ne signifie pas forcément que le déploiement a échoué.

Déployer avec GitHub Actions et OIDC

Ne stockez pas d’AWS Access Key dans GitHub Secrets. Créez un fournisseur OIDC et un rôle de déploiement dans AWS, puis limitez la trust policy au dépôt et à la branche.

{
  "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: eu-west-3

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

La policy du rôle dépend du modèle CDK bootstrap, du rôle d’exécution CloudFormation et des règles de l’organisation. Évitez AdministratorAccess en production. Une approche réaliste consiste à restreindre OIDC, utiliser des permission boundaries si nécessaire, puis réduire les permissions avec IAM Access Analyzer.

Ajouter des garde-fous de coût

Une petite API serverless peut coûter cher en cas de boucle, spam ou logs excessifs. Le stack inclut throttling, usage plan et reserved concurrency. Ajoutez aussi AWS Budgets.

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

Les budgets peuvent mettre du temps à afficher graphes et notifications. Configurez-les avant le lancement.

Rollback et pièges fréquents

Pour un premier service Lambda + API Gateway, le rollback le plus simple est souvent de revenir sur le mauvais commit et de redéployer.

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

Puis vérifiez API, événements CloudFormation et 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

Trois pièges reviennent souvent : modifier la console AWS après CDK, mettre des secrets dans les variables d’environnement ou les logs, et activer les traces de corps de requête API Gateway en production. Le stack ci-dessus garde dataTraceEnabled: false, mais la revue humaine reste indispensable.

Demander une revue avant déploiement

Utilisez Claude Code comme reviewer, avec preuves.

Fais une revue avant déploiement AWS.
Vérifie:
- Si le CDK diff ajoute des wildcards IAM excessifs
- Si Lambda lit les secrets uniquement depuis Secrets Manager
- Si API Gateway a throttling, usage plan et logging
- Si CloudWatch Logs peut exposer des données personnelles ou des corps complets
- Si les étapes de rollback sont documentées
- Si npm test, cdk synth et cdk diff sont passés

Retourne un tableau avec severity, file, line et fix.

Claude Code n’est pas l’approbateur final de production. Les frontières de compte, le risque de coût et les exceptions sécurité restent humains. Il sert à rendre la revue répétable.

Conclusion

La valeur de Claude Code dans un déploiement AWS n’est pas seulement d’écrire du CDK plus vite. Elle consiste à relier architecture, IaC, CI/CD, IAM, secrets, logs, rollback et coûts dans une pratique déployable.

Pour une petite API web, Lambda + API Gateway + CDK suffit souvent. Passez à ECS/Fargate quand l’application a vraiment besoin de conteneurs toujours actifs. Utilisez S3 + CloudFront ou Amplify pour une charge surtout frontend. Gardez le premier périmètre petit, revu et réversible.

Si votre équipe veut adapter les règles Claude Code, CDK, GitHub Actions OIDC, IAM minimal et checks opérationnels à un dépôt réel, réservez une session de consulting Claude Code. Masa peut examiner votre dépôt et votre historique AWS pour produire un plan directement implémentable.

En pratique, une petite API de génération de leads comme celle-ci peut être déployée en une demi-journée à une journée si le compte AWS est prêt. La partie sensible n’est pas la Lambda, mais IAM, les secrets, le rollback et la visibilité des coûts. Claude Code accélère l’implémentation ; les humains gardent la responsabilité du risque de production.

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