Over the past few months I’ve seen the article “Do not use AWS CloudFormation” by Greg Swallow make the rounds a couple of times. While there are some valid reasons you could prefer Terraform, I don’t agree with many of the issues Greg has with CloudFormation. Some of the weaknesses he identifies, I’d even count as strengths! So here I’m going to go through and counter his points, following the structure of his piece. All quotes (in italics) are from Greg’s blog to provide context.
Indirection
With Terraform […] no intermediary sits between you and the service you’re controlling. Want an RDS instance? Terraform will make calls directly to the RDS API.
First of all, both Terraform and CloudFormation provide some level of indirection. CloudFormation converts a YAML or JSON template to a set of API calls. Terraform does the same, starting from an HCL template.
Having that transformation in the cloud can make it harder to see the underlying API responses, but that’s not because of the conversion between template and API. The same APIs are still getting called, and they will raise the same errors when there is something wrong with the requests. If you look in CloudTrail, you will see these requests together with the entire error message.
The way CloudFormation implements that translation layer (for newer resources) can add a second step after an API call fails. However, it also allows for standardized errors in other cases, like “Resource Already Exists” or “Only configurable when creating a resource”.
The prerequisite steps you have to take to use CloudFormation [StackSets] across multiple accounts also must be taken just to have CloudFormation spin up resources in multiple regions within the same account.
I’d argue that StackSets (and Service Catalog) are benefits of using CloudFormation. However, if they are too much overhead for a project, you can still deploy to multiple regions by adding a –region parameter to your deployment command. Although, by not using StackSets, you’d lose some convenience features, like being able to update multiple regions in parallel easily.
Logic
Terraform offers a rich set of data sources and transforming data with Terraform is a breeze.
I agree that CloudFormation could use more intrinsic functions, but that does not mean it’s severely lacking in functionality. In many cases, you can replace the missing functions by being stricter about the acceptable inputs.
Speed
AWS CloudFormation is S-L-O-W.
CloudFormation can seem slow because it tries very hard not to get into a state where your infrastructure is broken. Both CloudFormation and Terraform try to execute as much in parallel as possible (keeping dependencies between resources in mind). However, CloudFormation will not start deleting resources until every creation and update has been completed. On top of that, CloudFormation will validate that all actions (deletes included) finish before it considers the deployment complete.
Sync vs Async
Wrapping CI/CD tooling around AWS CloudFormation is […] a difficult matter of polling stack updates until the right stack state bubbles up from an aws cloudformation CLI query.
Here Greg argues that Terraform is better because polling for changes can be challenging to do. However, if you’re okay with executing a command-line tool (like Terraform), you can AWS CloudFormation deploy, and the AWS CLI will do all that for you.
Even without the CLI, running async comes with some significant advantages:
- You don’t have to worry about the build tool (or your laptop) crashing or losing internet connectivity
- Everyone with access to the AWS account can see when an update is in progress and poll independently for changes
- You don’t need a process that keeps running during the change. The deployment will keep running until it’s done.
Running 100% as a managed service also includes the following advantages:
- You don’t need to execute any code on your machine
- You don’t need to worry about different tool versions and upgrades between them
- You don’t need an access key with full admin permissions
- You get state management included by default (instead of having to configure it yourself).
That safer approach has the potential of doubling the time it takes to execute a change (assuming that a create/update takes as long as a delete), but having automatic rollbacks is frequently worth the extra time.
Portability
If you learn AWS CloudFormation, then guess what: you can’t take your skills with you. If you put forth the effort to learn Terraform, then you can take your skills to any other cloud.
While the workflow might stay the same, the resources that you create are going to be vastly different between clouds. The primary skill that you should learn (independently from the tool) is how AWS works. This will make your skills transferable between tools instead of between clouds. You wouldn’t expect carpenters to list their experience with a hammer (even if it’s useful for all kinds of projects): instead you want to know what they can build.
Importing existing resources
I can’t even begin to tell you how to import resources with AWS CloudFormation, and neither can AWS’s engineers.
This is pure hyperbole. Importing resources into CloudFormation is documented, and the console has a basic wizard.
If we ignore the exaggeration, there is indeed still room for improvement. While all new resource types should support importing, there is still a long tail of old resources that are not yet supported. “All resources should support resource import” is a valid point. However, CloudFormation was usable before the introduction of this feature. Whether this is a dealbreaker will depend on how frequently you expect to import unsupported resources.
Service Quotas
The list of quotas for the AWS CloudFormation service is just hilarious.
I don’t think that documented limitations are necessarily a bad thing, and I wonder how many of those quotas people actually run into. It’s been a long time since I had to look at that page.
TL;DR
CloudFormation makes different trade-offs than Terraform. Looking at its sharp edges without considering the advantages they bring is unfair.
Use the tool that matches your requirements. If you want safe deployments, tight integration within AWS, and minimal operational overhead, CloudFormation will probably fit the bill.