Short answer: if you are AWS-only and want AWS to manage state, CloudFormation (usually through CDK) is a sound default. If you manage more than AWS, such as Cloudflare, Datadog or GitHub, Terraform or its open fork OpenTofu usually wins on breadth and ecosystem. If your team wants real programming languages across many providers, Pulumi fits. This page compares them on scope, state, language, ecosystem, new-service support, rollback, multi-account and licensing.
All three turn a written description of your infrastructure into reality and keep it that way. They differ in who owns the state, how many providers they speak, what language you write, and how big the ecosystem is.
CloudFormation: you give AWS a YAML or JSON template, AWS creates a stack and keeps its state on AWS's side. SAM, much of CDK and Service Catalog build on it. CDK lets you write TypeScript, Python, Java, Go or C# and synthesizes a CloudFormation template, so treat it as CloudFormation with a better front end.
Terraform is provider-based: AWS is one of hundreds of providers, next to Google Cloud, Azure, Cloudflare, Datadog, GitHub, Okta and Kubernetes. You write HCL, see a plan, apply it, and you own the state file. Since 2023 Terraform is under the Business Source License, which led to OpenTofu, an MPL-licensed fork under the Linux Foundation. Below, "Terraform" means Terraform or OpenTofu unless the license matters.
Pulumi lets you write infrastructure in general-purpose languages and deploy to many clouds. It keeps state in Pulumi Cloud (its managed service) by default or in a self-managed backend such as S3. Its open-source engine is Apache 2.0.
AWS-only, want AWS-managed state and the newest services first: CloudFormation/CDK. Many providers and the biggest ecosystem: Terraform/OpenTofu. Real languages across clouds: Pulumi. Any of them, run with proper state, pipelines and policy, is a good outcome.
This is the biggest discriminator and often settles the question.
CloudFormation manages AWS resources only, but deeply: stack policies, change sets, drift detection, nested stacks, StackSets and Service Catalog without an intermediary. Terraform and Pulumi offer one workflow for AWS plus your CDN, DNS, monitoring, identity provider, GitHub and Kubernetes.
List everything you want under code in the next two years. If it is essentially AWS, CloudFormation or CDK loses you little. If it includes a second cloud or several SaaS platforms with mature providers, Terraform or Pulumi consolidates it. "Multi-cloud" is oversold for startups, but "multi-provider" is almost universal.
How each tool remembers what it created shapes daily operations more than anything else.
CloudFormation: AWS tracks every stack. No backend to set up, nothing to lose or lock. Built-in drift detection reports resources changed by hand; you reconcile by updating the stack.
Terraform: you run a remote backend, usually S3 with versioning and encryption. HashiCorp's S3 backend docs support locking in S3 itself (use_lockfile) and mark DynamoDB-based locking as deprecated. Done right, owning state gives you power: state mv to refactor, import to adopt existing resources, targeted removes. Done wrong (state on a laptop, no locking) it is the classic Terraform failure.
Pulumi: state lives in Pulumi Cloud by default, with locking, history and a UI handled for you, or in a self-managed backend if you want everything in your own account.
Drift: CloudFormation detects it on request; Terraform and Pulumi show it on every plan or preview, which teams often run on a schedule in CI. In all three, the real fix is cultural: make code the only path to change production.
The loudest argument, and the one CDK and Pulumi have changed most.
Terraform's HCL is a focused configuration language with variables, loops (for_each, count), conditionals, functions and modules. Most engineers read it within a day.
Raw CloudFormation YAML or JSON gets verbose, and dynamic logic through intrinsic functions (!Ref, !Sub, Fn::If) is clunky. That is the fairest complaint about CloudFormation, and CDK answers it.
CDK and Pulumi both give you a real language with types, IDE support and unit tests. CDK targets AWS through CloudFormation; Pulumi targets many clouds with its own engine. The risk with both is code that is too clever and hides what will be deployed. Terraform has CDKTF, but it sees far less use.
Most "CloudFormation is awful to write" takes are really about raw YAML. The fair comparison today is HCL vs CDK vs Pulumi, and it comes down to whether your team prefers a focused config language or a language it already uses.
You should not hand-write a production VPC or EKS cluster from scratch. How much you can pull off the shelf differs a lot.
Terraform's public Registry and the widely used terraform-aws-modules collection (VPC, EKS, RDS, ALB, IAM) encode years of practice and let a small team stand up sensible infrastructure in a few dozen lines. Terraform is also the broad-market default, so more engineers, answers and consultants already know it.
CloudFormation reuse runs through nested stacks, StackSets and quick-start templates. CDK narrows the gap with Constructs (high-level constructs can stand up a well-configured Fargate service in a few lines) and Construct Hub. Pulumi has its own registry and can use Terraform providers through bridging, so provider coverage is broad, though its community is smaller than Terraform's.
Two real CloudFormation advantages.
CloudFormation tends to support new AWS services and properties at or near launch, and CDK inherits that. Terraform depends on the separately maintained AWS provider, which moves fast but can lag for brand-new services. Pulumi's AWS Native provider is generated from the AWS Cloud Control API, so its coverage follows what AWS exposes there. For teams that adopt new AWS services months after launch, this rarely matters.
When a CloudFormation stack update fails, CloudFormation rolls the stack back to its last working state by default. Terraform and Pulumi stop where they failed, and you fix forward. Small, frequent changes behind CI gates manage this well, but automatic rollback is a real safety net for less experienced teams.
Serious AWS users end up with many accounts across regions. Each tool fans out differently.
CloudFormation has StackSets: define a template once and AWS deploys it across accounts and regions, with AWS Organizations integration so new accounts can enroll automatically.
Terraform teams usually keep separate state per account or environment (each assuming a role into its target account), often kept DRY with Terragrunt or HCP Terraform workspaces. Native CLI workspaces are often misunderstood; most teams do not use them to separate production from staging. Pulumi uses stacks per environment with per-stack config.
StackSets is less to build but AWS-only. The Terraform and Pulumi patterns take more assembly but span other providers too.
CloudFormation has no license question: it is a free AWS service, and CDK is Apache 2.0. Pulumi's open-source engine is Apache 2.0, with Pulumi Cloud as a paid managed option.
In August 2023 HashiCorp moved Terraform from the Mozilla Public License to the Business Source License 1.1. Using Terraform to manage your own infrastructure is not restricted; the BSL targets vendors offering Terraform as a competing product. The community forked the last MPL version into OpenTofu, which reads the same HCL, uses the same providers and modules, and is a common default for teams that want a guaranteed-open tool.
Stated plainly enough to act on.
The wider and more varied your infrastructure, the more Terraform or OpenTofu pulls ahead. The more it is pure AWS and the more you value managed state, the more CloudFormation or CDK holds its own. None of the three is a mistake when run well.
CloudRoute matches you with one vetted AWS partner who runs these tools in production, gives you a straight recommendation for your footprint, and builds the foundation: codebase, locked remote state, a plan and apply pipeline with policy checks, drift detection and a multi-account layout, with existing resources imported under code.
You pay the partner for an IaC build at its rates. If the work is part of a migration to AWS, a proof of concept or a new workload on AWS, your matched partner can file MAP, POC or incremental workload (IW) funding: typically $50K to $150K for startups. Depends on the workload; AWS approves. CloudRoute is free for startups. Partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.
The factors that drive the choice. No column is a wrong choice; this is about fit.
| Factor | Terraform / OpenTofu | CloudFormation / CDK | Pulumi |
|---|---|---|---|
| Cloud scope | AWS plus hundreds of providers | AWS only, deeply integrated | Many clouds and providers |
| State | You run it (S3 with locking, or HCP Terraform) | AWS-managed stacks | Pulumi Cloud or a self-managed backend |
| Language | HCL | YAML/JSON, or CDK in TypeScript, Python and more | TypeScript, Python, Go, C#, Java, YAML |
| Drift | Shown on every plan | Drift detection per stack | Shown on every preview or refresh |
| Ecosystem | Largest: Registry and terraform-aws-modules | Thinner; CDK Constructs help | Smaller community; can bridge Terraform providers |
| New AWS services | Can lag via the AWS provider | At or near launch | Follows the Cloud Control API for AWS Native |
| Failed deploy | Stops; fix forward | Automatic rollback by default | Stops; fix forward |
| Multi-account | Per-environment state, often with Terragrunt | StackSets with Organizations | Stacks per environment |
| License | Terraform BSL (fine for self-use); OpenTofu MPL | Free service; CDK Apache 2.0 | Engine Apache 2.0; Pulumi Cloud is paid |
| Best fit | Multi-provider, ecosystem-driven teams | AWS-only teams wanting managed state | Developer-heavy teams wanting real languages |
You fill in a short form: what you run today, what you want to move, test or build, your stage and your region.
We read your answers and pick one vetted AWS consulting partner that fits the work, the stack and the region. We reply within 24 hours; your matched partner reaches out within 5 business days.
Your matched partner scopes the work with you. Then it checks which partner-filed funding fits: MAP if you are moving to AWS, POC if you want to test something, or incremental workload (IW) funding if you are already on AWS and launching new work.
If the work qualifies, the partner files the funding request with AWS. AWS reviews it and decides. The amount depends on the workload.
CloudRoute is free for startups. Partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.
AWS Activate credits are separate, and you apply for them yourself. Use Activate Founders if no investor backs you. Use Activate Portfolio with the Org ID or invite from your VC, accelerator, incubator or angel group if it is an Activate Provider. A consulting partner cannot apply for Activate on your behalf.
CloudRoute matches you with one vetted AWS partner who runs these tools in production, gives you a straight recommendation for your footprint, and builds the foundation. CloudRoute is free for startups.