Skip to main content
πŸŽ“ Claude Code Masterclass Learn AI-assisted development on Udemy β€” plus the companion book on Leanpub & Amazon. Start Learning
CDK vs Terraform 2026: IaC Comparison with Code Examples
DevOps

CDK vs Terraform 2026: IaC Comparison with Code Examples

AWS CDK vs Terraform β€” language support, state management, multi-cloud capabilities, team workflows, and migration strategies with real-world benchmarks.

LB
Luca Berton
Β· 2 min read

At a Glance

FactorAWS CDKTerraform
LanguageTypeScript, Python, Java, C#, GoHCL (+ CDKTF for programming languages)
Cloud supportAWS onlyMulti-cloud + SaaS
StateCloudFormation (managed)Local or remote (self-managed)
Abstraction levelHigh (L2/L3 constructs)Low-medium (resources)
Drift detectionCloudFormation driftterraform plan
Learning curveLow (if you know the language)Medium (HCL is new)
EcosystemConstruct HubTerraform Registry (15K+ providers)

AWS CDK: Infrastructure in Your Language

CDK lets you define AWS infrastructure using real programming languages with loops, conditions, and abstractions:

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 ecs_patterns from 'aws-cdk-lib/aws-ecs-patterns';

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

    const vpc = new ec2.Vpc(this, 'ApiVpc', {
      maxAzs: 3,
      natGateways: 1,
    });

    const cluster = new ecs.Cluster(this, 'ApiCluster', { vpc });

    // L3 construct: creates ALB + ECS Service + Target Group + Security Groups
    new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'ApiService', {
      cluster,
      cpu: 512,
      memoryLimitMiB: 1024,
      desiredCount: 3,
      taskImageOptions: {
        image: ecs.ContainerImage.fromAsset('./api'),
        containerPort: 8080,
      },
      publicLoadBalancer: true,
    });
  }
}

CDK Construct Levels

  • *L1 (Cfn)**: Raw CloudFormation resources β€” 1:1 mapping
  • L2: Curated resources with sensible defaults and helper methods
  • L3 (Patterns): Multi-resource architectures in one construct

CDK Strengths

  • Type safety β€” compile-time errors catch misconfigurations
  • IDE support β€” autocomplete, inline docs, refactoring
  • Testable β€” unit test infrastructure with Jest/pytest
  • Abstractions β€” create reusable constructs for your org
  • No state management β€” CloudFormation handles it

CDK Limitations

  • AWS only (unless using CDKTF)
  • CloudFormation limits β€” 500 resources per stack, slow updates
  • Synthesized templates are huge β€” hard to debug
  • Breaking changes β€” CDK v2 constructs evolve fast

Terraform: Multi-Cloud Standard

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "terraform-state-prod"
    key    = "api/terraform.tfstate"
    region = "eu-west-1"
  }
}

resource "aws_vpc" "api" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name        = "api-vpc"
    Environment = var.environment
  }
}

resource "aws_ecs_cluster" "api" {
  name = "api-cluster"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

module "ecs_service" {
  source  = "terraform-aws-modules/ecs/aws//modules/service"
  version = "5.6.0"

  name        = "api"
  cluster_arn = aws_ecs_cluster.api.arn

  cpu    = 512
  memory = 1024

  container_definitions = {
    api = {
      image     = "${aws_ecr_repository.api.repository_url}:latest"
      port_mappings = [{
        containerPort = 8080
        protocol      = "tcp"
      }]
    }
  }

  desired_count = var.environment == "prod" ? 3 : 1
}

Terraform Strengths

  • Multi-cloud β€” AWS, Azure, GCP, Kubernetes, Datadog, PagerDuty, etc.
  • Mature ecosystem β€” 15,000+ providers on Registry
  • Plan before apply β€” terraform plan shows exact changes
  • State locking β€” prevents concurrent modifications
  • Import existing resources β€” terraform import
  • Stable β€” HCL changes rarely break existing code

Terraform Limitations

  • State management β€” your responsibility (S3+DynamoDB, Terraform Cloud)
  • HCL is limited β€” no real loops, limited string manipulation
  • Provider lag β€” new AWS features arrive weeks/months late
  • State file secrets β€” contains sensitive values in plaintext

Testing Infrastructure

CDK Testing

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

test('ECS service has 3 desired tasks', () => {
  const app = new cdk.App();
  const stack = new ApiStack(app, 'Test');
  const template = Template.fromStack(stack);

  template.hasResourceProperties('AWS::ECS::Service', {
    DesiredCount: 3,
  });
});

Terraform Testing

# tests/api_test.tftest.hcl (native Terraform tests)
run "creates_ecs_cluster" {
  command = plan

  assert {
    condition     = aws_ecs_cluster.api.setting[0].value == "enabled"
    error_message = "Container Insights must be enabled"
  }
}

Cost Comparison

AspectCDKTerraform
Tool costFreeFree (OSS) / $$$ (Cloud)
State hostingFree (CloudFormation)S3 (~$1/mo) or TF Cloud ($20/user/mo)
Deployment speedSlow (CFN)Fast (direct API)
Drift detectionFree (CFN)terraform plan (free)

When to Choose

Choose CDK when:

  • AWS-only infrastructure
  • Team has strong TypeScript/Python skills
  • You want high-level abstractions (L3 patterns)
  • You need compile-time safety
  • Existing CloudFormation investment

Choose Terraform when:

  • Multi-cloud or hybrid strategy
  • You need Kubernetes, Datadog, GitHub, etc. providers
  • Team values explicit, readable configs
  • You want import and state migration capabilities
  • Enterprise with Terraform Cloud/Enterprise

Consider CDKTF when:

  • You want CDK’s programming model with Terraform’s multi-cloud providers
import { TerraformStack } from 'cdktf';
import { AwsProvider } from '@cdktf/provider-aws';
import { Instance } from '@cdktf/provider-aws/lib/instance';

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new AwsProvider(this, 'aws', { region: 'eu-west-1' });
    new Instance(this, 'web', {
      ami: 'ami-0c55b159cbfafe1f0',
      instanceType: 't3.micro',
    });
  }
}

Free 30-min AI & Cloud consultation

Book Now