Skip to main content
Pulumi logo Pulumi logo
  1. Docs
  2. Infrastructure as Code
  3. Comparisons
  4. CDK vs. Terraform

CDK vs. Terraform vs. Pulumi

    AWS CDK, Terraform, and Pulumi all provision cloud infrastructure as code, but they differ in where they run and how an AI coding agent works with them. CDK compiles to CloudFormation and is AWS-only; Terraform uses its own HCL language across many clouds; Pulumi uses general-purpose languages (or HCL) across any cloud, with no synthesis or transpilation step between the code an agent writes and the errors it reads back.

    Which of CDK, Terraform, and Pulumi can an AI agent write most reliably?

    Recent research on LLM-generated infrastructure as code finds that raw syntax is mostly a solved problem: a 2025 study of LLM-generated CloudFormation, Terraform, and AWS CDK found more than 95% syntactic validity across all three formats, with the real gap in “semantic alignment and handling complex infrastructure patterns.” Syntax isn’t the differentiator; the verification loop is.

    A separate 2026 study, IaC-Eval v2, measured how much a tight feedback loop matters in practice: a 7B model’s pass rate on Terraform/AWS tasks rose from a 14.0% pass@1 baseline to 45.7% with active retrieval, and to 62.9% (7B model) and 84.4% (GPT-4o) once agents could iteratively refine against verifier feedback. The tighter and more direct that feedback loop, the better an agent performs.

    This is where the three tools diverge structurally. AWS CDK code passes through JSII and cdk synth into a CloudFormation template before anything is validated against real infrastructure; an agent’s errors surface against synthesized logical IDs one translation step removed from the code it wrote. Terraform’s terraform plan computes a resource-level diff without an intervening synthesis step, but HCL is a domain-specific language with limited abstraction, and tests live in a separate harness (terraform test) using dedicated .tftest.hcl files rather than alongside the resource code. Pulumi programs are written in the same general-purpose language (TypeScript, Python, Go, C#, Java, or HCL) the agent already uses elsewhere in the codebase, so a type checker, linter, and unit tests can catch errors before any cloud call, and pulumi preview returns a direct resource-level diff with no template-synthesis step.

    Pulumi’s own benchmark of Claude Opus 4.6 and GPT-5.2-Codex against equivalent Terraform and Pulumi generation tasks found that with Opus, the total cost of an agent completing a generation-plus-refactor pipeline was 41% lower with Pulumi than Terraform ($0.146 vs. $0.249), and that “the difference comes entirely from repair cycles: Pulumi needed zero repairs across both scenarios, while Terraform refactoring triggered self-repair on every run.” Fewer translation steps and more verifiers close to the code an agent wrote means fewer repair cycles, which is where the real cost and reliability gap shows up.

    How does each tool’s agent feedback loop actually work?

    • AWS CDK: code (TypeScript, Python, Java, C#, or Go via JSII) → cdk synth produces a CloudFormation template → cdk deploy hands the template to the CloudFormation service. An agent’s edits are validated by cdk diff and CloudFormation’s own drift detection, but failures surface against the synthesized template and roll back at the stack level, one step removed from the source the agent edited.
    • Terraform: HCL → terraform plan computes a resource-level diff → terraform apply. The plan step is fast and high-fidelity, but HCL has no native type system or general-purpose control flow, so an agent working across modules is reasoning in a DSL distinct from the rest of the codebase, and correctness checks beyond syntax require a separate test harness.
    • Pulumi: code in a general-purpose language → compiler/type-checker and unit tests run locally, before any cloud call → pulumi preview gives a resource-level diff in the same run. Every verifier available to that language’s toolchain (IDE, linter, type checker, test framework) applies directly to the infrastructure code, with no synthesis or transpilation step between what the agent wrote and what gets deployed.

    CDK vs. Terraform vs. Pulumi: feature comparison

    FeaturePulumiTerraformAWS CDK
    LanguagesTypeScript, Python, Go, C#, Java, YAML, and HCLHCL (a domain-specific language)TypeScript, Python, Java, C#, Go (via JSII)
    Language typeGeneral-purpose, plus a first-class HCL runtimeDomain-specificGeneral-purpose, compiled to a DSL output
    Cloud coverageAny cloud or SaaS via 200+ providersAny cloud via Terraform/OpenTofu providersAWS only
    Deploys throughPulumi’s own deployment engineTerraform CLI applies directlyAWS CloudFormation (CDK synthesizes to CFN templates)
    Preview/diffpulumi preview, resource-level, no synthesis stepterraform plan, resource-levelcdk diff, compares to synthesized CloudFormation template
    State managementPulumi Cloud (default), self-managed backends, or use Pulumi as a Terraform/OpenTofu state backendHCP Terraform, S3/other remote backends, or local stateCloudFormation stack state (AWS-managed)
    TestingNative unit/property tests in-language, run before any cloud callSeparate harness (terraform test, Terratest)Native unit tests in-language (CDK assertions library), against synthesized template
    Reusable abstractionsComponents, packages published to language package managersModulesConstructs, published as libraries via JSII
    Policy as codeBuilt-in (Pulumi Policies)Sentinel/OPA (HCP Terraform or separate tooling)CloudFormation Guard, cdk-nag (separate tooling)
    Secrets managementBuilt-in (Pulumi ESC)Vault or external integrationAWS Secrets Manager / SSM (external, AWS-only)
    Agent feedback loopShortest: same-language type checks, tests, and preview, no translation stepFast plan/apply, but a separate DSL and test harnessLongest: JSII binding layer, synthesis to CloudFormation, stack-level rollback
    LicenseApache 2.0 (open source)Business Source License (BUSL), IBM-owned since Feb. 2025Apache 2.0 (open source)
    Current version (measured 2026-08-07)CLI v3.256.0v1.15.8 (OpenTofu v1.12.5)v2.263.0

    How do CDK, Terraform, and Pulumi differ on multi-cloud reach?

    AWS CDK is scoped to AWS: it synthesizes to CloudFormation, and CloudFormation only understands AWS (and a small set of third-party resource types registered with it). No supported path exists to provision Azure, Google Cloud, or Kubernetes resources from a CDK app without stepping outside CDK entirely.

    Terraform and Pulumi both provision any cloud through a provider ecosystem. The Terraform Registry lists 7,000+ providers (measured 2026-08-07), and OpenTofu — the Linux Foundation-stewarded fork created after Terraform’s 2023 license change — reports 3,900+ providers and 23,600+ modules (measured 2026-08-07). Pulumi supports 200+ providers, many derived from the same open-source Terraform provider schemas, plus native providers for AWS, Azure, and Kubernetes with no bridging layer.

    How does each tool manage state?

    CDK relies entirely on CloudFormation’s own stack state; there is no separate state file to manage, but there is also no state backend choice to make; you get CloudFormation’s model or nothing.

    Terraform and OpenTofu track state in a file, typically stored remotely (HCP Terraform, an S3 bucket, or another supported backend). Pulumi defaults to Pulumi Cloud as a managed state backend, but as of 2026 can also run as the state backend for existing Terraform or OpenTofu configurations via a standard backend "remote" block, with no change to how .tf files are authored.

    How do you test infrastructure in each tool?

    CDK ships a unit testing library (aws-cdk-lib/assertions) that asserts against the synthesized CloudFormation template, in the same language as the app. Terraform testing lives in a separate harness rather than alongside the resource code: terraform test runs dedicated .tftest.hcl files, and third-party options like Terratest are written in Go regardless of what deployed the infrastructure. Pulumi programs are ordinary code, so they use the same unit and property-testing frameworks (Jest, pytest, Go’s testing package, and so on) already used for application code in that language, and those tests can run before any cloud call is made.

    How do the ecosystems and communities compare?

    Terraform has the largest and oldest provider ecosystem by raw count (7,000+ providers in the Terraform Registry, measured 2026-08-07), reflecting nearly a decade as the default IaC tool. OpenTofu, forked from Terraform in 2023 after HashiCorp’s license change to BUSL, inherited that same provider compatibility and has grown its own module registry (23,600+ modules, per search.opentofu.org, measured 2026-08-07) under Linux Foundation governance. AWS CDK’s ecosystem is the Construct Hub, which indexes reusable constructs for CDK (and for CDK8s and CDKTF); the AWS-only constraint comes from CloudFormation, the deployment target, rather than from the construct ecosystem itself. Pulumi’s registry spans 200+ pre-built providers, mixing native providers (built directly against cloud provider APIs, including Kubernetes and Azure Native) with providers bridged from Terraform’s schemas — and any Terraform provider can be adapted into a Pulumi provider on demand, so the registry count isn’t the ceiling on what’s reachable from Pulumi.

    When should you choose each one?

    • Choose AWS CDK if your infrastructure is AWS-only for the foreseeable future, your team already standardizes on CloudFormation for governance or compliance reasons, and you want native integration with AWS-specific tooling like SAM or CDK Pipelines.
    • Choose Terraform (or OpenTofu) if you have deep existing HCL investment, a team fluent in Terraform’s module ecosystem, and no near-term need for general-purpose language features like loops, testing frameworks, or shared libraries across infrastructure and application code.
    • Choose Pulumi if you want multi-cloud coverage in a general-purpose language your team (and your AI agents) already write, want infrastructure tests to run in the same framework as application tests, or want to keep existing .tf files and Terraform workflows while gaining a faster agent feedback loop and Pulumi Cloud’s collaboration features.

    None of these is a universally correct choice; teams with heavy CloudFormation tooling or Terraform module investment have real switching costs that this comparison doesn’t erase.

    Frequently asked questions

    Can AWS CDK do multi-cloud?

    No. AWS CDK synthesizes to AWS CloudFormation templates, and CloudFormation only provisions AWS resources (plus a limited set of third-party resource types registered with it). Teams that need genuine multi-cloud coverage from a single tool typically choose Terraform, OpenTofu, or Pulumi instead.

    Is Pulumi a Terraform replacement or a CDK replacement?

    Both, depending on what you’re replacing. Pulumi replaces CDK for teams that want the same general-purpose-language model without being locked to AWS and CloudFormation. Pulumi also replaces Terraform for teams that want the same multi-cloud provider coverage with real languages and tests instead of HCL — and, if you’re not ready to leave HCL, Pulumi can run as a drop-in state backend for existing Terraform or OpenTofu configurations with no rewrite required.

    What happened to CDK for Terraform (CDKTF)?

    CDK for Terraform, a separate HashiCorp project that let you write Terraform configurations in TypeScript, Python, Java, C#, or Go, was deprecated on December 10, 2025, and its GitHub repository has been archived. See Pulumi vs. CDKTF for migration paths.

    Can I use my existing AWS CDK constructs with Pulumi?

    Not directly; CDK constructs are JSII-based and synthesize to CloudFormation, while Pulumi programs run through Pulumi’s own deployment engine. Migrating means re-expressing constructs as Pulumi components, though the underlying AWS resource shapes are usually similar since both ultimately model the same AWS APIs. See the AWS CDK migration guide for the recommended path.

    Can I keep writing HCL and still use Pulumi?

    Yes. Pulumi supports HCL as a first-class language (runtime: hcl in Pulumi.yaml), running ordinary .tf files as a superset of Terraform’s HCL, and separately can serve as the state backend for Terraform or OpenTofu configurations you don’t want to touch at all. See HCL on Pulumi for details.

    Which of the three deploys fastest?

    It depends on the resources and account topology more than the tool itself; all three ultimately wait on the same underlying cloud provider APIs. Where the tools differ is iteration speed during development: Pulumi’s pulumi preview and Terraform’s terraform plan both give a fast resource-level diff without a synthesis step, while CDK’s cdk diff compares against a freshly synthesized CloudFormation template, adding a step to each iteration.

    Do I have to migrate everything at once?

    No. All three tools support incremental adoption. Pulumi can import existing resources managed by CDK, CloudFormation, or Terraform without recreating them, and its Terraform state backend support lets you adopt Pulumi Cloud for existing Terraform-managed infrastructure before rewriting any configuration.

    Next steps

      The infrastructure as code platform for any cloud.