AWS CDK v2 vs Terraform : quel IaC choisir en 2026 ?
← Retour au blogIaC

AWS CDK v2 vs Terraform : quel IaC choisir en 2026 ?

3 décembre 202510 min de lectureAWS CDKTerraformIaC

AWS CDK permet d'écrire l'infrastructure en TypeScript ou Python, tandis que Terraform reste le standard multi-cloud. Quel outil choisir selon votre contexte en 2026 ?

Deux philosophies différentes

AWS CDK (Cloud Development Kit) et Terraform représentent deux approches fondamentalement différentes de l'Infrastructure as Code. Terraform adopte une approche déclarative : vous décrivez l'état final souhaité en HCL, et Terraform calcule le plan pour y parvenir. AWS CDK adopte une approche impérative : vous écrivez du code TypeScript ou Python qui génère des templates CloudFormation, avec toute la puissance d'un vrai langage de programmation.

En 2026, les deux outils ont atteint une maturité remarquable et coexistent souvent dans les mêmes organisations. Choisir entre les deux dépend de votre contexte : cloud strategy, compétences de l'équipe, et complexité de l'infrastructure.

Les concepts clés du CDK

Le CDK s'organise autour de trois concepts hiérarchiques :

  • App : le point d'entrée de votre programme CDK, contient une ou plusieurs stacks
  • Stack : unité de déploiement CloudFormation, correspond à un template CF
  • Construct : brique de base réutilisable représentant une ou plusieurs ressources AWS

Les constructs existent à trois niveaux :

  • L1 (CfnXxx) : wrapper direct des ressources CloudFormation, 1:1 avec CF
  • L2 : abstractions haut niveau avec des valeurs par défaut sensibles (opinionated)
  • L3 (Patterns) : architectures complètes prêtes à l'emploi (ex: ApplicationLoadBalancedFargateService)

Comparaison côte à côte : service ECS Fargate

Voici le même service ECS Fargate défini en CDK TypeScript et en Terraform HCL :

CDK TypeScript

import { Stack, StackProps } from 'aws-cdk-lib';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecs_patterns from 'aws-cdk-lib/aws-ecs-patterns';
import { Construct } from 'constructs';

export class PaymentServiceStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const cluster = new ecs.Cluster(this, 'Cluster', {
      clusterName: 'payment-cluster',
      containerInsights: true,
    });

    const service = new ecs_patterns.ApplicationLoadBalancedFargateService(
      this, 'PaymentService', {
        cluster,
        cpu: 512,
        memoryLimitMiB: 1024,
        desiredCount: 2,
        taskImageOptions: {
          image: ecs.ContainerImage.fromRegistry('nginx:latest'),
          containerPort: 8080,
          environment: { NODE_ENV: 'production' },
        },
        publicLoadBalancer: true,
      }
    );

    // Auto-scaling intégré en 3 lignes
    const scaling = service.service.autoScaleTaskCount({ maxCapacity: 10 });
    scaling.scaleOnCpuUtilization('CpuScaling', { targetUtilizationPercent: 70 });
  }
}

Terraform HCL

resource "aws_ecs_cluster" "main" {
  name = "payment-cluster"
  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

resource "aws_ecs_task_definition" "payment" {
  family                   = "payment-service"
  cpu                      = "512"
  memory                   = "1024"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  execution_role_arn       = aws_iam_role.ecs_exec.arn
  container_definitions = jsonencode([{
    name      = "app"
    image     = "nginx:latest"
    portMappings = [{ containerPort = 8080 }]
    environment = [{ name = "NODE_ENV", value = "production" }]
  }])
}

resource "aws_ecs_service" "payment" {
  name            = "payment-service"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.payment.arn
  desired_count   = 2
  launch_type     = "FARGATE"
  network_configuration {
    subnets          = var.private_subnets
    security_groups  = [aws_security_group.app.id]
    assign_public_ip = false
  }
  load_balancer {
    target_group_arn = aws_lb_target_group.payment.arn
    container_name   = "app"
    container_port   = 8080
  }
}
# ... 50+ lignes supplémentaires pour ALB, SG, IAM, Auto Scaling

CDK réduit drastiquement le volume de code pour AWS grâce aux constructs L3, mais Terraform donne un contrôle granulaire sur chaque paramètre.

CDK Aspects : compliance automatisée

Les Aspects CDK permettent d'appliquer des règles de conformité transversalement à toutes les ressources d'une stack. C'est une fonctionnalité sans équivalent direct dans Terraform :

class SecurityAspect implements cdk.IAspect {
  visit(node: IConstruct): void {
    if (node instanceof s3.Bucket) {
      if (!node.encryptionKey) {
        cdk.Annotations.of(node).addError(
          'All S3 buckets must use customer-managed KMS keys'
        );
      }
    }
    if (node instanceof rds.DatabaseInstance) {
      if (!node.storageEncrypted) {
        cdk.Annotations.of(node).addError('RDS must have encryption enabled');
      }
    }
  }
}

// Appliquer l'aspect à toute la stack
cdk.Aspects.of(app).add(new SecurityAspect());

Tests CDK avec Jest

CDK permet de tester l'infrastructure comme du code applicatif, avec des assertions sur les templates générés :

import { Template } from 'aws-cdk-lib/assertions';

test('ECS service has correct CPU allocation', () => {
  const app = new cdk.App();
  const stack = new PaymentServiceStack(app, 'TestStack');
  const template = Template.fromStack(stack);

  template.hasResourceProperties('AWS::ECS::TaskDefinition', {
    Cpu: '512',
    Memory: '1024',
    RequiresCompatibilities: ['FARGATE'],
  });
});

test('S3 buckets have versioning enabled', () => {
  template.allResourcesProperties('AWS::S3::Bucket', {
    VersioningConfiguration: { Status: 'Enabled' },
  });
});

Avantages de Terraform

  • Multi-cloud natif : même workflow pour AWS, GCP, Azure, OVH, Kubernetes
  • Communauté massive : 3000+ providers, modules Terraform Registry
  • OpenTofu : fork open-source sans dépendance commerciale
  • Stabilité : HCL est moins susceptible de breaking changes qu'un SDK
  • Séparation dev/ops : les ops peuvent contribuer sans maîtriser TypeScript

Avantages du CDK

  • Type safety : le compilateur TypeScript détecte les erreurs avant le deploy
  • IDE autocomplete : découverte des APIs sans consulter la documentation
  • Réutilisabilité : les constructs sont des packages npm partageable entre équipes
  • Testing : tests unitaires natifs de l'infrastructure
  • Abstractions puissantes : L3 patterns réduisent radicalement le volume de code

Matrice de décision

ContexteRecommandation
Équipe 100 % AWS, forte culture TypeScript/PythonCDK
Multi-cloud (AWS + GCP, ou AWS + OVH)Terraform / OpenTofu
Équipe mixte dev + ops sans culture de programmationTerraform
Startup AWS-only qui scale viteCDK (productivité maximale)
Infrastructure complexe partagée entre plusieurs équipesTerraform (modules) ou CDK (constructs npm)
Compliance et security policies à appliquer partoutCDK Aspects ou Sentinel (Terraform)

Conclusion

En 2026, CDK et Terraform ne sont plus vraiment en compétition — ils répondent à des besoins différents. Si votre organisation est AWS-centric et que vos développeurs écrivent déjà du TypeScript, CDK offre une productivité inégalée. Si vous gérez plusieurs clouds, si vous voulez une gouvernance simple, ou si vos équipes ops n'ont pas de culture de programmation, Terraform (ou OpenTofu) reste le choix le plus sage. De nombreuses organisations utilisent les deux : CDK pour les services applicatifs AWS, Terraform pour la fondation réseau et multi-cloud.

← Retour au blog