Skip to content
IaC

CDK vs Terraform in 2025: the honest comparison

28 June 2026 · 7 min read

The CDK vs Terraform question comes up in almost every infrastructure conversation I have. Teams starting a greenfield AWS project want to know which one to pick. Teams already using one want to know if they chose wrong. Teams using both want to know how to stop.

The honest answer is that neither tool is objectively better. They reflect different philosophies about what infrastructure code is for, and the right choice depends on factors that are specific to your organisation. This article tries to lay those factors out clearly so you can make the call for your context rather than picking the one with the better marketing.

What each tool actually is

Terraform is a declarative infrastructure tool with its own configuration language (HCL). You describe the desired state of your infrastructure, Terraform computes the diff against the current state, and applies the changes. It works across every major cloud provider and hundreds of third-party services. State is stored externally (typically S3 + DynamoDB for AWS teams) and is the source of truth for what Terraform believes is deployed.

AWS CDK is an imperative infrastructure framework that generates CloudFormation templates. You write infrastructure in a general-purpose programming language — TypeScript, Python, Java, Go, or C# — and CDK synthesises it into CloudFormation JSON/YAML, which CloudFormation then deploys. State is owned by CloudFormation, not CDK. CDK is AWS-only.

That last sentence matters more than people acknowledge. CDK is not an alternative to Terraform in the general sense — it’s an alternative to writing CloudFormation by hand, with the benefit of a real programming language. When you pick CDK, you’re also picking CloudFormation as your deployment engine, with all of CloudFormation’s constraints and behaviours.

Where CDK wins

The language is a genuine advantage. Writing infrastructure in TypeScript means you get real type checking, IDE autocompletion, refactoring tools, and the ability to reuse the same testing frameworks your application code uses. HCL is readable and well-designed, but it is a limited DSL — loops are verbose, conditionals are awkward, and there’s no escape hatch when the abstraction doesn’t fit.

CDK constructs are also a meaningful abstraction layer. An L2 construct like aws_lambda.Function sets secure defaults, wires IAM permissions, and handles the boilerplate that every Lambda needs. A well-written L3 construct can encode your organisation’s standards — logging configuration, tagging strategy, security policies — and enforce them at the point of use rather than in a checklist. If your team is building opinionated internal platforms, CDK constructs are the right primitive for distributing those opinions.

CloudFormation drift detection is built in. Because CDK deploys via CloudFormation, you get cdk diff against the live CloudFormation state, and CloudFormation’s native drift detection for individual resources. If someone changes a security group rule in the console, CloudFormation knows.

The AWS integration is first-class. CDK often adds support for new AWS services and features before the Terraform AWS provider does, and the CDK team can ship constructs that encode AWS best practices (Origin Access Control for CloudFront, not OAI; VPC endpoints for service isolation) as the defaults rather than the opt-in.

Where Terraform wins

Multi-cloud and multi-service coverage is unmatched. If your infrastructure includes AWS, Cloudflare, GitHub, PagerDuty, and a Kubernetes cluster, Terraform can manage all of it from a single tool with a consistent workflow. CDK stops at AWS (technically there are CDK adapters for Terraform and Kubernetes, but they add complexity rather than reducing it).

The plan is explicit and auditable. terraform plan produces a human-readable diff that shows exactly what will be created, modified, or destroyed, with the proposed values. This is useful for code review, for compliance workflows that require change approval, and for teams that are still building trust in their IaC process. CDK’s cdk diff is similar but produces CloudFormation changeset output, which is less readable and less complete — it doesn’t always show the final resource property values that will be applied.

State management is explicit and portable. Terraform state is a JSON file you control. You can inspect it, migrate it, split it, and reason about it. CloudFormation state is opaque — it lives in CloudFormation and you interact with it only through AWS APIs. This is usually fine, but when something goes wrong (stuck stack, failed rollback, resource import), Terraform gives you more direct control.

The ecosystem maturity is broader. Terraform modules have been shared, tested, and refined in the open for over a decade. The terraform-aws-modules collection covers most common AWS patterns with production-hardened implementations. CDK’s construct library is growing but thinner, and construct quality varies significantly between official AWS constructs and community ones.

HCL’s constraints are also its strength. The limited expressiveness of HCL means infrastructure tends to be more uniform and readable across teams. With CDK, the full power of TypeScript means infrastructure can become arbitrarily complex — dynamic constructs, conditional logic, runtime-generated resource names — in ways that are hard to audit and harder to debug when something fails.

The real decision factors

After the feature comparison, the questions that actually determine the right answer:

Is your team AWS-only, or multi-cloud? If you’re committed to AWS and plan to stay that way, CDK’s AWS-first design is a feature. If you have meaningful infrastructure outside AWS today — or a reasonable chance of it in the next two years — Terraform’s provider model is the safer foundation.

What languages does your team know well? CDK in the language your team knows well is excellent. CDK in a language nobody is fluent in is a maintenance problem. If your team is Python-heavy and your CDK code is TypeScript because someone thought it would be cleaner, you’ve created an adoption barrier that will slow down every infrastructure change.

What’s your org’s policy stance on third-party tooling? Some organisations — especially those with compliance requirements or large enterprise security review processes — prefer to minimise the number of external tools. CloudFormation is an AWS-managed service; Terraform is a third-party tool with its own release cadence, licensing terms (the BSL change in 2023 matters for some teams), and dependency on HashiCorp’s continued investment. If your organisation is already committed to Terraform’s commercial offerings or OpenTofu, this is moot. If not, it’s worth considering.

How much do you trust AWS to own your abstraction layer? CDK is fundamentally a bet that AWS will maintain the framework, keep constructs current with new service features, and not break your code in major version upgrades. AWS CDK v2 was a disruptive migration from v1. The framework has had periods where community constructs lagged behind service updates. This is manageable, but it’s a dependency you’re accepting.

What I’d recommend today

For a new AWS-only project with a TypeScript or Python team: CDK is the better starting point. The language advantages, the L2/L3 construct library, and the AWS integration quality outweigh the limitations if you’re staying in the AWS ecosystem. Use cdk diff in CI, store your context in a versioned JSON file, and invest in L3 constructs for your opinionated platform defaults.

For a multi-cloud or multi-service project, or a team that already has Terraform expertise: Terraform is the safer bet. The plan readability, provider coverage, and module ecosystem make it the more productive choice when your surface area extends beyond AWS.

For teams already committed to one or the other: the switching cost is almost always higher than the marginal benefit of the other tool. Unless you have a specific pain point that the other tool definitively solves — multi-cloud coverage, type-safe constructs, plan auditability — the right move is usually to invest in doing your current tool better rather than migrating.

The question worth asking first

Before you decide between CDK and Terraform, ask whether your infrastructure code is actually causing problems. Many teams switch tools because the grass looks greener, not because their current tool is the bottleneck. Unresolved drift, poor testing, lack of module structure, and no change review process will cause the same pain regardless of which tool you use.

CDK and Terraform are both good enough. The discipline around them is what separates teams that ship infrastructure confidently from teams that treat every deploy as a risk.