Skip to content
Cloud

What is Infrastructure as Code? Terraform vs Pulumi vs CDK Compared

Compare Terraform, AWS CDK, and Pulumi for Infrastructure as Code. Covers languages, state management, multi-cloud support, pricing, and practical guidance on choosing the right tool.

A
Abhishek Patel10 min read

Infrastructure engineer with 10+ years building production systems on AWS, GCP,…

What is Infrastructure as Code? Terraform vs Pulumi vs CDK Compared
What is Infrastructure as Code? Terraform vs Pulumi vs CDK Compared

Fifteen Years of Infrastructure Tooling in Five Turns

It is worth knowing how we got here, because the current IaC debate (Terraform vs AWS CDK vs Pulumi) makes sense only as a reaction to what came before. The timeline is shorter than most people realise.

  1. 2006-2011 -- shell scripts and AMI bakes: the first generation was #!/bin/bash plus a jump host. State lived in someone's head. Puppet (2005) and Chef (2009) formalised configuration management for existing servers but not provisioning -- you still clicked "launch instance" in the console.
  2. 2011-2014 -- CloudFormation and Heat: AWS shipped CloudFormation in 2011, bringing declarative provisioning to one cloud. JSON (and later YAML) templates gave you repeatability, but vendor lock-in was total and error messages were catastrophic.
  3. 2014 -- Terraform: HashiCorp released Terraform with HCL and a multi-cloud provider model. The plan/apply loop and a shared state file became the default mental model for an entire decade.
  4. 2018-2019 -- Pulumi and AWS CDK: the general-purpose-language camp arrived. Pulumi (2018) offered TypeScript/Python/Go for any cloud; AWS CDK (2019) offered the same languages but synthesised down to CloudFormation.
  5. 2023 -- the BSL fork: HashiCorp relicensed Terraform to BSL 1.1. The Linux Foundation forked it as OpenTofu in September 2023. Every serious IaC conversation now includes a licensing footnote that did not exist eighteen months earlier.

Everyone agrees infrastructure should be code. The meaningful question in 2026 is which code -- HCL, TypeScript, Python -- and whose runtime executes it. This guide compares the three tools that dominate real-world decisions, with the licensing, state, and language trade-offs that actually matter.

Why IaC Matters: The Core Benefits

  1. Reproducibility -- deploy identical environments for dev, staging, and production from the same code
  2. Auditability -- every change is a Git commit with an author, timestamp, and review trail
  3. Speed -- spinning up a new environment goes from days of manual work to a single pipeline run
  4. Drift detection -- compare the actual state of your infrastructure to what the code declares
  5. Disaster recovery -- rebuild your entire infrastructure from code if a region goes down

The Big Three: Terraform vs CDK vs Pulumi

FeatureTerraformAWS CDKPulumi
LanguageHCL (domain-specific)TypeScript, Python, Java, C#, GoTypeScript, Python, Go, C#, Java, YAML
Cloud supportMulti-cloud (AWS, GCP, Azure, 3000+ providers)AWS onlyMulti-cloud (AWS, GCP, Azure, Kubernetes)
State managementRemote backends (S3, Terraform Cloud)CloudFormation stacksPulumi Cloud or self-managed backends
Dry-runterraform plancdk diffpulumi preview
Maturity2014, massive ecosystem2019, AWS-maintained2018, growing ecosystem
LicenseBSL 1.1 (was MPL 2.0)Apache 2.0Apache 2.0
Learning curveLow (HCL is simple) to medium (modules)Medium (need to know CloudFormation concepts)Low if you know the language

Terraform: The Industry Standard

How It Works

You write .tf files in HCL (HashiCorp Configuration Language), run terraform plan to see what will change, and terraform apply to execute. Terraform maintains a state file that maps your code to real resources.

resource "aws_s3_bucket" "data" {
  bucket = "my-app-data-bucket"

  tags = {
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.data.id
  versioning_configuration {
    status = "Enabled"
  }
}

Strengths

  • Largest provider ecosystem -- 3,000+ providers covering every cloud and SaaS product
  • HCL is purpose-built and readable, even for non-developers
  • Massive community: Stack Overflow answers, blog posts, and pre-built modules for everything
  • terraform plan gives clear, predictable diffs before any change

Weaknesses

  • HCL lacks loops, conditionals, and abstractions that general-purpose languages provide (though for_each and dynamic blocks help)
  • State file management is a source of bugs -- state locks, state corruption, and manual state surgery are real operational burdens
  • The BSL license change in 2023 led to the OpenTofu fork, creating ecosystem fragmentation

AWS CDK: Infrastructure in Real Languages

How It Works

CDK lets you define AWS resources using TypeScript, Python, or other supported languages. Under the hood, CDK synthesizes your code into CloudFormation templates and deploys them as CloudFormation stacks.

import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

export class DataStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string) {
    super(scope, id);

    new s3.Bucket(this, 'DataBucket', {
      bucketName: 'my-app-data-bucket',
      versioned: true,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });
  }
}

Strengths

  • Use real programming languages with IDE autocompletion, type checking, and refactoring tools
  • L2 and L3 constructs provide sensible defaults -- a single new ApplicationLoadBalancedFargateService() creates an ALB, ECS service, task definition, security groups, and IAM roles
  • CloudFormation handles state management, rollbacks, and drift detection
  • AWS maintains it -- first-class support for new AWS services

Weaknesses

  • AWS-only. If you use GCP or Azure alongside AWS, CDK can't manage those resources.
  • CloudFormation is slow. Large stacks take 10-30 minutes to deploy.
  • CloudFormation's 500-resource limit per stack forces you to split large applications into multiple stacks.
  • Debugging CloudFormation errors through CDK adds an abstraction layer that obscures the real problem.

Pulumi: Multi-Cloud with Real Languages

How It Works

Pulumi uses general-purpose languages to define infrastructure, similar to CDK, but it manages state directly (no CloudFormation intermediary). It supports AWS, GCP, Azure, Kubernetes, and dozens of other providers.

import * as aws from '@pulumi/aws';

const bucket = new aws.s3.Bucket('data-bucket', {
  bucket: 'my-app-data-bucket',
  versioning: { enabled: true },
  tags: {
    Environment: 'production',
    ManagedBy: 'pulumi',
  },
});

Strengths

  • Multi-cloud with real languages -- the best of both CDK and Terraform
  • Direct state management (no CloudFormation) means faster deployments
  • Pulumi AI and the converter tool can translate Terraform HCL to Pulumi code
  • Built-in secrets management -- encrypted in state by default

Weaknesses

  • Smaller ecosystem and community than Terraform
  • Pulumi Cloud (the managed backend) is a paid service for teams; self-managed backends work but require more setup
  • Some Terraform providers don't have Pulumi equivalents yet

For reference: Infrastructure as Code (IaC) is the practice of managing and provisioning computing infrastructure through machine-readable configuration files -- typically HCL, TypeScript, Python, or YAML -- rather than manual console clicks. IaC enables version control, peer review, automated deployment, and drift detection as first-class capabilities.

State Management Compared

AspectTerraformAWS CDKPulumi
State storageS3 + DynamoDB, Terraform CloudCloudFormation (managed by AWS)Pulumi Cloud, S3, local file
State lockingDynamoDB or Terraform CloudBuilt into CloudFormationBuilt into Pulumi Cloud
Drift detectionterraform plan (compares state to cloud)CloudFormation drift detectionpulumi refresh
Import existing resourcesterraform importcdk importpulumi import

Pricing and Tooling

  • Terraform CLI -- free (BSL license). Terraform Cloud free tier: 500 managed resources. Team tier: $20/user/month.
  • AWS CDK -- free. CloudFormation is free (you pay only for provisioned resources).
  • Pulumi CLI -- free (Apache 2.0). Pulumi Cloud Individual: free. Team: $50/user/month. Enterprise: custom pricing.
  • OpenTofu -- free fork of Terraform under MPL 2.0, maintained by the Linux Foundation.
  • Infracost -- shows cost estimates in Terraform pull requests. Free for open source, $50+/month for teams.
  • Spacelift -- CI/CD for Terraform/Pulumi/CloudFormation. Starts at $40/month.

Failure Modes: What Actually Breaks in Production

Everyone writes the happy-path tutorial. These are the sharp edges that turn a 10-minute change into a weekend.

Terraform State Lock Contention

Two CI jobs kick off simultaneously against the same workspace. One grabs the DynamoDB lock, the other sits in Acquiring state lock for twenty minutes and times out. The lock orphans. The only fix is terraform force-unlock <id>, which feels terrifying because it is. Either serialise IaC runs through Terraform Cloud / Atlantis / Spacelift, or accept that every CI platform needs an explicit mutex.

CDK Stack Resource Limit

CloudFormation's 500-resource-per-stack limit is not visible in CDK code. A team built a monolithic cdk.Stack that synth'd to 503 resources and every deploy failed with a CFN error nobody had seen before. The refactor -- splitting across nested stacks -- took ten days. Design for multiple stacks from day one.

Pulumi Secret Rotation Breaks Plan Output

Pulumi stores secrets encrypted in state. Rotate the KMS key and existing state becomes unreadable until you run pulumi stack export + pulumi stack import with the new key. Not a crash, just a 45-minute recovery while production deploys are queued behind you.

Provider Version Drift Between Laptops

Developer A's local Terraform uses AWS provider 5.12, developer B's uses 5.67. The plan output differs for the same code because provider defaults changed between versions. Always pin required_providers with an exact constraint, and commit the .terraform.lock.hcl file.

Choosing: A Decision Tree for Real Teams

The comparison table gives you the features; the choice depends on constraints you already have.

  1. Single-cloud AWS shop, TypeScript team: AWS CDK. The L2/L3 constructs save weeks of boilerplate and CloudFormation's rollback semantics are genuinely nice once you stop fighting them.
  2. Multi-cloud (AWS + GCP, AWS + Azure): Terraform or OpenTofu. The provider ecosystem is unmatched, and HCL is boring in a good way.
  3. Multi-cloud with a Go/Python team that hates HCL: Pulumi. Real languages, real test frameworks, and the pulumi convert --from tf path lets you start from existing Terraform code.
  4. Regulated industry with BSL licensing concerns: OpenTofu. Drop-in replacement, MPL 2.0, Linux Foundation governance.
  5. Kubernetes-only infrastructure: Crossplane or Kubernetes-native tools. None of the three in this guide are ideal if every resource is a Kubernetes CRD.

Pro tip: whatever you pick, invest in modules / components early. The long-term cost of IaC is not the tool -- it is how often you reinvent the same VPC + subnet + IAM scaffolding across projects. A good internal module library pays for itself in weeks.

Frequently Asked Questions

Which IaC tool should a beginner start with?

Start with Terraform. It has the largest community, the most learning resources, and skills transfer to any cloud provider. HCL is simpler than learning a general-purpose language's IaC patterns. Once you're comfortable with IaC concepts, you can evaluate CDK or Pulumi if their strengths align with your needs.

Can I use Terraform and CDK together?

Yes, but carefully. Some teams use Terraform for shared infrastructure (networking, DNS) and CDK for application-specific resources. The key is clear ownership boundaries -- don't manage the same resource from both tools. Use Terraform outputs and CDK's Fn.importValue to pass values between them.

What is OpenTofu and should I use it?

OpenTofu is a community fork of Terraform created after HashiCorp changed Terraform's license from MPL 2.0 to BSL 1.1. It's maintained by the Linux Foundation and is a drop-in replacement for Terraform. If the BSL license is a concern for your organization, OpenTofu is a viable alternative with growing community support.

How do I handle secrets in IaC?

Never store secrets in plain text in your IaC files. Terraform integrates with Vault, AWS Secrets Manager, and SSM Parameter Store via data sources. CDK can reference Secrets Manager and SSM parameters directly. Pulumi encrypts secrets in state by default and integrates with cloud KMS services.

Is CloudFormation still worth learning?

Only if you're deep in the AWS ecosystem and need to understand what CDK generates under the hood. Writing raw CloudFormation YAML/JSON is tedious compared to CDK or Terraform. However, understanding CloudFormation concepts (stacks, change sets, rollbacks) is valuable because CDK depends on them.

How do I migrate from manual infrastructure to IaC?

Use import commands (terraform import, cdk import, pulumi import) to bring existing resources under IaC management without recreating them. Start with the most critical resources (networking, databases) and work outward. Tools like Former2 can generate CloudFormation or Terraform from existing AWS resources automatically.

Pick a Tool and Commit

The worst IaC decision is using three tools across five teams. Pick one primary tool, standardize on it, and invest in modules and patterns that your team can reuse. Terraform is the safe default. CDK is the right choice for AWS-only shops that want TypeScript end-to-end. Pulumi is compelling for multi-cloud teams that want real languages without CloudFormation's limitations. All three are production-proven -- the choice matters less than consistency.

A

Written by

Abhishek Patel

Infrastructure engineer with 10+ years building production systems on AWS, GCP, and bare metal. Writes practical guides on cloud architecture, containers, networking, and Linux for developers who want to understand how things actually work under the hood.

Related Articles

Enjoyed this article?

Get more like this in your inbox. No spam, unsubscribe anytime.

Comments

Loading comments...

Leave a comment

Stay in the loop

New articles delivered to your inbox. No spam.