CloudFormation vs Terraform: Why AWS’ Native IaC Falls Behind

CloudFormation vs Terraform: Why AWS’ Native IaC Falls Behind

If you’ve ever had the misfortune of dealing with CloudFormation, you’ve probably encountered some version of rollback hell. You deploy a stack, something goes wrong, and now you’re stuck in an endless loop of failed updates. AWS’ solution? Delete the entire stack and start over—hope you enjoy losing everything you just spent hours debugging.

Meanwhile, Terraform offers a completely different experience. Instead of waiting for AWS to clean up after itself, Terraform manages state externally and allows for targeted updates. Need to modify a single resource? No problem. With CloudFormation, you might be forced to redeploy half your infrastructure just to make a simple change.

But rollback issues aren’t the only reason engineers hate working with CloudFormation. The slow update cycle is another major problem. AWS frequently launches new features, but CloudFormation often lags months (or even years) behind in supporting them. Need to deploy DynamoDB Global Tables or WAF GeoMatchSets? Sorry, CloudFormation still doesn’t support them. In contrast, Terraform updates its AWS provider much faster, sometimes within weeks of a new AWS feature release.

And let's not forget validation—or the lack thereof. CloudFormation doesn’t properly check for syntax errors before executing a deployment. That means you might wait 30 minutes for a stack to roll out, only for it to fail at the very last step due to a simple typo. Worse, rollback takes just as long, wasting an hour just to fix something as trivial as a misnamed parameter. With Terraform, syntax errors are caught upfront, and if something does fail, you can fix it without tearing everything down.

Another frustrating limitation of CloudFormation is its lack of support for referencing existing resources. Need to look up an existing VPC ID, IAM role, or S3 bucket? Too bad—you have to pass it in as a parameter. Terraform, on the other hand, provides data sources, allowing you to reference existing AWS resources dynamically. This makes it far easier to integrate with existing infrastructure rather than forcing everything into CloudFormation’s rigid stack model.

That said, Terraform isn’t perfect either. Managing a large state file in Terraform can be a nightmare, especially in environments with hundreds of resources. If the state file gets corrupted or lost, recovering from it can be a major pain. But tools like Terragrunt solve this problem by breaking infrastructure into smaller, independently managed modules, reducing the risk of state bloat.

Another common Terraform complaint is code duplication. Unlike CloudFormation, which supports nested stacks, Terraform lacks a built-in mechanism to reuse configurations across multiple environments easily. This leads to a lot of copy-pasting between dev, staging, and production. Again, Terragrunt steps in with its hierarchical configuration system, allowing you to define infrastructure once and reuse it across different environments without unnecessary duplication.

At the end of the day, if you’re deploying AWS-only infrastructure and don’t mind CloudFormation’s quirks, it might be tolerable. But for engineers who value speed, flexibility, and sanity, Terraform—especially with Terragrunt—is the clear winner.

Overwhelmed by AWS?

Struggling with infrastructure? We streamline your setup, strengthen security & optimize cloud costs so you can build great products.

Related AWS best practices blogs

Looking for more interesting AWS blog posts?

Automatically scaling AWS Fargate tasks vertically

When you define a task definition with Fargate you must set the memory and CPU usage of the tasks (and optionally the individual containers) before starting the tasks.

Read more

Amazon Cognito vs. Auth0: Why Cognito is a Nightmare

Choosing between Amazon Cognito and Auth0 for authentication? One is cheap but frustrating, the other is powerful but expensive—so which one actually works?

Read more

Implementing Zero-Trust in AWS

Zero Trust Architecture (ZTA) is a security model that operates on the principle of "never trust, always verify." This approach is crucial in cloud environments like AWS, where resources are distribut ...

Read more

Managing multiple AWS accounts in the same browser

Recently, AWS introduced a feature that makes managing multiple AWS accounts in the same browser much easier, simplifying workflows for developers and engineers alike.

Read more

Reduce your AWS CloudFront costs by switching to Cloudflare

When you have an application behind CloudFront that is read-heavy (like most static websites) you will find that the AWS CloudFront costs can be a nasty surprise on your AWS bill. These costs can be v ...

Read more
ES Cloud

Terraform and for_each

In this article I explain the use of ‘for_each’ in Terraform through examples. I explain how it handles different data types and ways to resolve common errors.

Read more

Terraform module for Prowler security scans

As a solution architect one of the pillars for a solution is cost. There are a lot of paid security scanners for your AWS accounts out there but most of them are quite pricey. For start-ups this cost ...

Read more