Every team managing AWS infrastructure eventually has to decide: Terraform or CloudFormation?
Both are mature, production-grade infrastructure-as-code tools. Both will get the job done. The choice matters for different reasons than most teams think — and it’s less about the tools themselves and more about where your team is going.
Here’s a practical breakdown.
What they actually are
CloudFormation is AWS’s native IaC service. You write templates in YAML or JSON that describe your desired AWS resources. CloudFormation manages the deployment lifecycle — create, update, delete — and maintains a live view of your stack state in the service itself. No external state file to manage.
Terraform is HashiCorp’s open-source IaC tool. It uses its own HCL syntax, supports AWS via a provider, and stores state in a backend you manage (S3 + DynamoDB is the standard for AWS). It can also provision resources across any other cloud provider or service that has a Terraform provider.
The fundamental difference: CloudFormation is a service running in AWS. Terraform is a tool running on your machine (or CI runner) that talks to AWS APIs and tracks what it created.
Where CloudFormation wins
AWS-native integration. CloudFormation gets new AWS service support on or before launch day. When AWS releases a new feature, the CloudFormation resource type is usually available immediately or within days. Terraform’s AWS provider typically follows within weeks to months, but there’s always a lag.
If you’re on a new service or feature the day it launches, CloudFormation is often the only IaC option.
No state management. CloudFormation’s state is stored in the service. There’s no S3 bucket, no DynamoDB table, no locking configuration to set up. For small teams or infrequent operators, this is a meaningful reduction in operational overhead.
AWS Service Catalog and Control Tower integration. AWS’s governance tooling — Service Catalog products, Control Tower customizations, account vending — is CloudFormation-native. If you’re operating at scale with multi-account governance, CloudFormation is the lower-friction path for those integrations.
CDK targets CloudFormation. If your team wants to write IaC in a programming language (TypeScript, Python, Go, Java), AWS CDK compiles down to CloudFormation. So “CDK vs Terraform” is a more apt comparison than “CloudFormation vs Terraform” for language-native workflows.
Where Terraform wins
Multi-cloud and third-party resources. If you’re managing AWS infrastructure alongside GCP, Azure, Cloudflare, PagerDuty, Datadog, GitHub, or virtually anything else with an API, Terraform’s provider ecosystem is unmatched. One tool, consistent workflow, unified state.
Developer experience. Terraform’s HCL is generally considered more readable than CloudFormation YAML, particularly for complex configurations with many resources. The plan output is clearer about what will change. Loops, conditionals, and modules feel more natural.
State import and drift detection. terraform import lets you bring existing infrastructure under Terraform management. terraform plan will show you when real-world state has drifted from your code. CloudFormation has drift detection too, but Terraform’s workflow for handling drift is more integrated.
Community and ecosystem. The Terraform Registry has a large library of community-maintained modules. For common patterns (VPC, EKS, RDS), there are well-maintained modules that save significant time. CloudFormation has CloudFormation Registry modules and AWS Quick Starts, but the breadth is narrower.
The practical decision framework
Choose CloudFormation if:
- Your stack is AWS-only and you expect it to stay that way
- You’re using AWS Control Tower or Service Catalog and want native integration
- You want to use CDK (it compiles to CloudFormation anyway)
- Your team doesn’t have Terraform expertise and doesn’t want to build it
- You’re provisioning infrastructure that uses cutting-edge AWS features on launch day
Choose Terraform if:
- You have multi-cloud infrastructure, even if AWS is primary
- You’re integrating AWS infrastructure with third-party services (DNS, monitoring, CI/CD)
- Your team already has Terraform expertise or strong prior HCL familiarity
- You need flexible state management (remote state, workspace isolation, module composition)
- Developer experience and
planoutput readability matter to your team
Both is fine, but pick a primary. Some organizations use CloudFormation for AWS-specific governance resources (Organizations, Control Tower) and Terraform for everything else. This is defensible, but it means maintaining two workflows. Default to one and reach for the other only when there’s a clear reason.
The migration question
If you have existing CloudFormation stacks and you’re considering moving to Terraform (or vice versa), be clear-eyed about the cost. “Migrating to Terraform” typically means:
- Write Terraform equivalents of existing resources
- Import existing resources into Terraform state (
terraform import) - Carefully validate that the Terraform config matches the deployed resources
- Remove the CloudFormation stacks after Terraform takes over
This is feasible but non-trivial for large stacks. The breakeven point depends on how much ongoing maintenance cost the migration saves. For small environments, the migration may never pay back the time invested. For large, actively developed platforms, it often does.
One thing to avoid: running CloudFormation and Terraform managing the same resources concurrently. The state conflict is a source of incidents.
What this looks like in practice
Most mature AWS environments I work with have landed on one of three patterns:
All-Terraform. EC2, RDS, networking, DNS, monitoring alerting, CI/CD secrets — all in Terraform. CloudFormation is not in use. Common at product companies that grew up on AWS and adopted Terraform early.
CloudFormation for governance, Terraform for product. Control Tower account customizations and SCPs in CloudFormation; application infrastructure in Terraform. Clean separation, two toolchains to maintain.
CDK everywhere. Team writes TypeScript or Python, CDK synthesizes CloudFormation, CloudFormation deploys. Often a deliberate choice by teams that want type safety and language-native constructs.
None of these is wrong. The failure mode is not picking one and ending up with ad-hoc YAML scattered across three tools with no one who owns the state.
When to bring in help
IaC architecture decisions have long tails. The choice you make today determines what your CI/CD pipeline, state management, and environment promotion workflow look like for the next 3–5 years.
If you’re setting up infrastructure from scratch or evaluating a migration, I can help you make the right call for your team’s specific context — and build out the initial patterns so you’re not starting from scratch.
Contact me or email nick@coldsmokeconsulting.com.
Nick Allevato is an AWS Certified Solutions Architect Professional with 20 years of infrastructure experience. He runs Cold Smoke Consulting, an independent AWS consulting practice.