Use Cases

Claude Code × AWS CloudFormation/CDK Guide Complet | Générez votre Infrastructure comme Code Automatiquement

Accélérez l'Infrastructure as Code AWS avec Claude Code. Code fonctionnel pour les templates CloudFormation, les stacks CDK TypeScript et l'architecture multi-stack — basé sur l'expérience réelle de Masa en production.

« Je déteste devoir cliquer dans la console AWS à chaque fois pour configurer l’infrastructure » — si vous vous êtes déjà dit ça, vous n’êtes pas seul. CloudFormation et CDK rendent l’infrastructure reproductible par le code, mais écrire ces templates prend du temps.

Je gère l’infrastructure de ce site (Cloudflare Pages + Workers + D1) avec Claude Code, et pour l’infrastructure AWS en production, je laisse également Claude Code générer les templates CloudFormation/CDK. Les templates qui prenaient des heures sont maintenant terminés en 1/5 du temps.


CloudFormation vs CDK : lequel choisir ?

CloudFormation: Service natif AWS qui décrit l'infrastructure en JSON/YAML
CDK (Cloud Development Kit): Framework qui décrit l'infrastructure en TypeScript/Python
                              et la synthétise en CloudFormation
ComparaisonCloudFormationCDK
LangageJSON / YAMLTypeScript, Python, Java, etc.
Sécurité des typesAucuneExcellente (totalement type-safe avec TypeScript)
RéutilisabilitéFaible (copier-coller)Haute (abstraite avec des classes et fonctions)
Courbe d’apprentissageFaibleMoyenne
Compatibilité Claude CodeExcellenteRemarquable

Pour les nouveaux projets, CDK TypeScript est fortement recommandé. Sa compatibilité avec Claude Code est remarquable et, combinée à l’autocomplétion des types, elle produit du code de haute qualité.


Étape 1 : Convertir des ressources AWS existantes en CloudFormation

Un pattern utile quand vous voulez codifier un environnement AWS existant après coup.

claude -p "
Convertis la configuration AWS suivante en template CloudFormation (YAML).

[Configuration actuelle]
- VPC : 10.0.0.0/16, 2 sous-réseaux publics, 2 sous-réseaux privés
- EC2 : t3.medium, Amazon Linux 2023, dans le sous-réseau public
- RDS : MySQL 8.0, db.t3.micro, dans le sous-réseau privé
- ALB : HTTPS (certificat ACM), transfert vers EC2
- Groupes de sécurité : autoriser 443 depuis l'ALB, autoriser 3306 depuis EC2 vers RDS uniquement

[Exigences]
- Environnement (dev/staging/prod) commutable via paramètre
- Préfixer les noms de ressources avec le nom de l'environnement
- Afficher le nom DNS de l'ALB dans les Outputs CloudFormation
"

Template CloudFormation généré (extrait) :

AWSTemplateFormatVersion: "2010-09-09"
Description: "Web Application Infrastructure"

Parameters:
  Environment:
    Type: String
    AllowedValues: [dev, staging, prod]
    Default: dev
  DBPassword:
    Type: String
    NoEcho: true  # Masquer le mot de passe

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub "${Environment}-vpc"

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs ""]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "${Environment}-public-1"

  # Groupe de sécurité ALB
  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ALB Security Group
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0

Outputs:
  ALBDnsName:
    Value: !GetAtt ApplicationLoadBalancer.DNSName
    Export:
      Name: !Sub "${Environment}-alb-dns"

Étape 2 : Construire un stack serverless avec CDK

Avec CDK, on écrit en TypeScript, ce qui facilite la réutilisation de la logique.

# Initialiser le projet CDK
mkdir my-infra && cd my-infra
npx cdk init app --language typescript

claude -p "
Implémente la configuration serverless suivante en CDK TypeScript dans lib/my-infra-stack.ts.

[Configuration]
- API Gateway (REST API) + Lambda (Node.js 20)
- Table DynamoDB (PAY_PER_REQUEST)
- Bucket S3 (privé, versioning activé)
- CloudFront (origine S3, support domaine personnalisé)
- Passer le nom de la table DynamoDB et le nom du bucket S3 en variables d'environnement Lambda
- Attacher automatiquement un rôle IAM de moindre privilège à Lambda

Tagger toutes les ressources de manière appropriée,
et activer la protection contre la suppression en production (NODE_ENV=production).
"

Code CDK généré :

// lib/my-infra-stack.ts
import * as cdk from "aws-cdk-lib";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as origins from "aws-cdk-lib/aws-cloudfront-origins";

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

    const isProd = process.env.NODE_ENV === "production";

    // Table DynamoDB
    const table = new dynamodb.Table(this, "AppTable", {
      partitionKey: { name: "PK", type: dynamodb.AttributeType.STRING },
      sortKey: { name: "SK", type: dynamodb.AttributeType.STRING },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      pointInTimeRecovery: true,
      deletionProtection: isProd,
      removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
    });

    // Bucket S3
    const bucket = new s3.Bucket(this, "AssetsBucket", {
      versioned: true,
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      encryption: s3.BucketEncryption.S3_MANAGED,
      deletionProtection: isProd,
      removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
    });

    // Fonction Lambda
    const apiLambda = new lambda.Function(this, "ApiLambda", {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: "index.handler",
      code: lambda.Code.fromAsset("src/lambda"),
      environment: {
        TABLE_NAME: table.tableName,
        BUCKET_NAME: bucket.bucketName,
        NODE_ENV: process.env.NODE_ENV ?? "development",
      },
      timeout: cdk.Duration.seconds(30),
      memorySize: 512,
    });

    // Accorder les permissions minimales à Lambda
    table.grantReadWriteData(apiLambda);
    bucket.grantReadWrite(apiLambda);

    // API Gateway
    const api = new apigateway.RestApi(this, "AppApi", {
      restApiName: "MyApp API",
      defaultCorsPreflightOptions: {
        allowOrigins: apigateway.Cors.ALL_ORIGINS,
        allowMethods: apigateway.Cors.ALL_METHODS,
      },
    });

    api.root.addProxy({
      defaultIntegration: new apigateway.LambdaIntegration(apiLambda),
    });

    // CloudFront
    const distribution = new cloudfront.Distribution(this, "Distribution", {
      defaultBehavior: {
        origin: new origins.S3Origin(bucket),
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
    });

    // Sorties
    new cdk.CfnOutput(this, "ApiUrl", { value: api.url });
    new cdk.CfnOutput(this, "CloudFrontUrl", { value: distribution.distributionDomainName });
  }
}

Étape 3 : Mettre à jour des stacks existants et vérifier les différences

# Vérifier les différences avant le déploiement
npx cdk diff

# Demander à Claude Code d'expliquer les différences
claude -p "
Lis la sortie de cdk diff et explique en français ce qui a changé.
Prête une attention particulière aux modifications des groupes de sécurité et des politiques IAM.

$(npx cdk diff 2>&1)
"

Étape 4 : Concevoir une architecture multi-stack

L’infrastructure à l’échelle de la production est gérée en la divisant en plusieurs stacks.

claude -p "
Conçois la configuration multi-stack suivante en CDK TypeScript.

[Stratégie de division des stacks]
- NetworkStack : VPC, sous-réseaux, groupes de sécurité
- DatabaseStack : RDS, ElastiCache (dépend de NetworkStack)
- ApplicationStack : ECS, ALB, AutoScaling (dépend de NetworkStack, DatabaseStack)
- MonitoringStack : Tableaux de bord CloudWatch, alarmes, notifications SNS

Inclure les dépendances entre stacks et comment utiliser CfnOutput / Fn.importValue.
"
// bin/app.ts
import * as cdk from "aws-cdk-lib";
import { NetworkStack } from "../lib/network-stack";
import { DatabaseStack } from "../lib/database-stack";
import { ApplicationStack } from "../lib/application-stack";
import { MonitoringStack } from "../lib/monitoring-stack";

const app = new cdk.App();
const env = { account: process.env.CDK_ACCOUNT, region: "eu-west-1" };

const network = new NetworkStack(app, "NetworkStack", { env });
const database = new DatabaseStack(app, "DatabaseStack", { env, vpc: network.vpc });
const application = new ApplicationStack(app, "ApplicationStack", {
  env,
  vpc: network.vpc,
  database: database.cluster,
});
new MonitoringStack(app, "MonitoringStack", {
  env,
  alb: application.alb,
  database: database.cluster,
});

Étape 5 : Confier le debugging CloudFormation/CDK à Claude Code

Claude Code peut également aider à résoudre les échecs de déploiement.

claude -p "
CDK deploy échoue avec l'erreur suivante.
Explique la cause et comment la corriger :

$(npx cdk deploy 2>&1 | tail -30)
"

Patterns d’échec courants :

  • ROLLBACK_COMPLETE : Le déploiement précédent a échoué, laissant le stack cassé → exécuter cdk destroy puis redéployer
  • UPDATE_ROLLBACK_FAILED : Conflit avec des modifications manuelles → résoudre manuellement dans la console AWS
  • Resource already exists : Collision de noms avec une ressource existante → renommer la ressource ou l’importer

4 pièges courants

1. Contourner la protection contre la suppression avec cdk destroy

Dans les environnements de développement, les ressources resteront après cdk destroy si on ne définit pas removalPolicy: DESTROY. En production, utiliser RETAIN pour éviter les suppressions accidentelles.

2. Ignorer la détection de dérive CloudFormation

Quand vous modifiez des ressources manuellement dans la console AWS, CloudFormation se désynchronise avec la réalité (dérive). Exécutez la détection de dérive dans la console CloudFormation une fois par mois.

3. Écrire les secrets directement dans les templates

# Mauvais : le mot de passe reste dans le template
DBPassword: "mysecretpassword"

# Bon : récupérer depuis Secrets Manager ou Parameter Store
DBPassword: !Sub "{{resolve:secretsmanager:prod/db-password}}"

4. Négliger l’épinglage des versions CDK

Si les versions CDK ne sont pas alignées dans l’équipe dans package.json, des différences apparaîtront. Committer package-lock.json pour s’assurer que tout le monde utilise la même version.


Récapitulatif

TâcheContribution de Claude Code
Génération CloudFormationYAML complet en décrivant simplement les exigences
Implémentation CDKCode d’infrastructure type-safe en TypeScript
Conception de stacksArchitecture de dépendances multi-stack
Explication des diffsSortie cdk diff expliquée en français
DebuggingCause et solution à partir des logs d’erreur

L’Infrastructure as Code, c’est quelque chose qu’on sait tous devoir faire mais qu’on remet toujours à plus tard. Avec Claude Code, on décrit juste « la configuration AWS dont j’ai besoin » et le template est prêt — la barrière à l’adoption de l’IaC s’abaisse considérablement.

Articles connexes

Références

#claude-code #aws #cloudformation #cdk #iac #typescript

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.