How do Terraform and CloudFormation differ? In short, Terraform is an open-source Infrastructure as Code tool that has the ability to deploy resources to multiple cloud providers, while CloudFormation is an AWS service designed specifically for provisioning AWS resources.
In this blog post, we will be comparing these two most common Infrastructure as Code options, Terraform and AWS CloudFormation, and outlining some of the key differences between them.
What is Terraform?
Terraform is an Infrastructure as Code tool created by HashiCorp. Terraform utilizes a syntax called the HashiCorp Configuration Language (HCL), which allows users to define their infrastructure programmatically.
One of the most notable benefits of Terraform is that it provides the ability to deploy resources to multiple cloud providers, which makes it dare I say - "cloud agnostic."
Although the term cloud-agnostic is often used when discussing Terraform, just because you are using Terraform doesn't automatically make you "multi-cloud" or any more cloud agnostic than if you were using AWS CloudFormation. This is because you won't be able to re-use the same code you're using for one cloud provider (e.g., AWS), to deploy resources to another cloud provider (e.g., Azure). Instead, you'll end up creating code specifically for each cloud provider.
In addition to the "multi-provider" support that Terraform provides, there are other benefits to consider as well, such as its ability to dynamically create resources using it's for_each
or count
features and the ability to dynamically configure properties of a resource with the dynamic
block functionality.
Additionally, Terraform supports built-in functions that can be called and used within your code, which become very useful for everyday tasks.
Providers & Resource Types
Speaking of providers, Terraform itself has the concept of "providers", which you'll need to define and configure within your code explicitly. The provider configuration is where you specify things like how you are authenticating into a particular AWS account and what region will be used for the resources you're trying to deploy. When using a provider, each provider has its selection of "resource types", which are the literal items you define your code to create.
These resource types are typically cloud resources; for most folks, that's what we are ultimately looking to define and deploy at the end of the day. When deploying resources, you'll find that the provider name is embedded within the resource type name for a given resource, which helps users understand what provider they are currently using.
For example, if you were looking to create an Amazon S3 Bucket, you would be using the aws_s3_bucket
resource type. Based on this naming being prefixed with aws_
, you can tell that this resource type is within the aws
provider. Pretty convenient, right?
Most useful Terraform features
Terraform features include:
- Support for virtually any cloud provider and other platforms through Terraform providers
- Declarative configuration using HashiCorp Configuration Language (HCL)
- Execution plans - see what is going to happen to your infrastructure resources before actually applying the changes
- Resource graph - build a graph of all your resources and identify the dependencies between them
- State management - tracks the state of your infrastructure, making it easy to determine what kind of changes have to be made to your infrastructure
- Loops, conditionals, and dynamic blocks for reusability
- Strong community and ecosystem
Note: New versions of Terraform will be placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that will expand on Terraform's existing concepts and offerings. It is a viable alternative to HashiCorp's Terraform, being forked from Terraform version 1.5.6. OpenTofu retained all the features and functionalities that had made Terraform popular among developers while also introducing improvements and enhancements. OpenTofu is not going to have its own providers and modules, but it is going to use its own registry for them.
What is AWS CloudFormation?
AWS CloudFormation is an AWS service that is designed specifically for provisioning AWS resources. You have a choice of using either YAML or JSON syntax for writing your AWS CloudFormation code, both of which are natural choices for many users.
Given AWS CloudFormation is AWS's native language and service for infrastructure as code, you will likely find more official quickstarts provided by AWS in the language. In addition to this, AWS Support will probably be more capable of assisting you with issues when you need help. AWS Support is essential for large enterprises, particularly those new to the cloud or slow to adopt. These types of organizations may have a skill gap within their organization regarding their cloud skill set, and in turn, they are more likely to use AWS Enterprise Support.
Historically speaking, one of the primary reasons users would pick a tool such as Terraform over CloudFormation was the lack of support for modules. When using AWS CloudFormation, you previously needed to utilize nested templates to achieve re-usable code -- and may still follow this approach today.
Fortunately, though, in November 2020, AWS introduced support for AWS CloudFormation modules, allowing for a new way to create re-usable code. There are, of course, other significant differences between the two languages, which we will be exploring in the following section.
Read more: What is AWS Cloudformation?
Most useful CloudFormation features
CloudFormation features include:
- AWS support
- YAML/JSON templates to define your AWS infrastructure
- Execution plans via Change Sets
- Custom resources -- allows you to integrate third-party resources and APIs into your CloudFormation-managed infrastructure
- Rollback and automatic resource deletion
- Cross-region and cross-account deployment
💡 You might also like:
Differences between Terraform and CloudFormation
1) Code Syntax
The syntax between Terraform and CloudFormation is probably the most apparent major differentiator, as many users are already familiar with writing YAML and JSON-based templates compared to Terraform's HCL syntax.
Granted, many users find HCL reasonably straightforward to learn.
2) Learning curve
The learning curve for Terraform can be considered moderate, as it has straightforward syntax and support for multiple cloud providers. However, understanding its state management, modules, and provider ecosystem can take some time. Terraform's approach to infrastructure as code across multiple clouds (not just AWS) means learners also need to grasp provider-specific nuances.
For CloudFormation, the learning curve might be steeper for those not familiar with JSON's strict syntax. However, for users already deeply integrated into the AWS ecosystem, learning CloudFormation could feel more natural as it is designed specifically for AWS resources and services. The integration with AWS services means that users need to understand AWS offerings and how they interact.
3) Dynamic Features
Dynamically creating and configuring resources is a powerful feature that Terraform provides that CloudFormation currently cannot match within its standard features. AWS does offer an extension to CloudFormation called the Serverless Application Model (SAM), as well as an entirely separate tool called the AWS Cloud Development Kit (CDK), but in this case, we are focusing on standard CloudFormation features.
The Terraform count
and Terraform for_each
functionality allows you to create logic to create a resource multiple times dynamically. Furthermore, you can dynamically configure your resource using the dynamic
block feature. AWS CloudFormation, on the other hand, is much less dynamic and more explicit. With CloudFormation, you will need to define a given resource multiple times (or modularize the resource and call the given module numerous times) to create resources repeatedly.
4) Usable Functions
The ability to use built-in functions within your code can have tremendous benefits.
In Terraform, you have access to many different types of functions. A few example categories of Terraform functions include numeric, string manipulation, encoding, date/time, and filesystem -- and this is not the complete list!
In comparison, CloudFormation is extremely limited, providing less than 15 intrinsic functions in total. The lack of helper functions can lead to annoying, complicated situations for basic tasks.
For example, if you're simply looking to obtain the date or time within your CloudFormation template, there's no built-in function for this. Instead, you'll need to create a custom resource within your template that calls a lambda function that returns the information you need.
5) State Management
When using Terraform, users will be quickly introduced to the concept of "state." Terraform state represents stored information about your deployed infrastructure and configuration (a list of what resources have been created).
This "state" is a file created once you run the terraform apply
command to deploy the resources you defined in your code. You'll need to come up with a process for maintaining your Terraform state file, whether that's storing it in an Amazon S3, utilizing Spacelift's managed state feature, or other means. The default functionality of Terraform is to keep your state locally, which is problematic when attempting to use Terraform collaboratively.
With AWS CloudFormation, this is simply something you don't have to worry about, as CloudFormation deployments are represented within the CloudFormation service as a "stack" -- showing the deployment result/events of the resources that were created/updated/deleted based on the CloudFormation template you deployed.
6) Cloud Providers
AWS CloudFormation, as the name suggests, is specific to Amazon Web Services. You can theoretically achieve deployment to third-party resources through the use of custom resources, but this is rather hacky, and at the end of the day, those third-party resources are not truly supported by CloudFormation.
On the other hand, Terraform allows you to deploy to other cloud providers as well. Granted, you won't be able to re-use the same codebase from one cloud provider to another. At the very least, when using Terraform, you'll have familiar syntax and methods for deploying to different cloud providers. For some companies, this is a significant benefit, as being able to use the same syntax and deployment methods to deploy to multiple cloud providers is a clear plus.
7) Community and documentation
Being provider-agnostic gives Terraform the edge when it comes to community. Many organizations contribute modules and providers to the ecosystem, but sometimes, this means that documentation can be as good as the provider's documentation itself.
CloudFormation has an active AWS community, that is smaller when compared to Terraform's. The documentation is very thorough but can be overwhelming. Integration with AWS-specific features and services is well-documented, which is beneficial for users fully committed to the AWS ecosystem.
8) Cost
Terraform is free to run, and CloudFormation doesn't incur that much cost ($0.0009 per handler operation + $0.00008 per second for handler operation duration after the first free 30 seconds), but you will need to pay the cost of the resources you are spawning with them.
9) Enterprise Support
If your organization uses AWS Enterprise Support, this certainly provides peace of mind knowing that AWS can assist you directly when/if you have issues with your AWS CloudFormation.
This is in comparison to Terraform, where you can also obtain support from HashiCorp directly or through the open-source community. For users that are all-in on AWS, the ability to have native knowledgeable support for your Infrastructure as Code tool is a significant benefit.
Terraform and AWS CloudFormation use cases
In this section, we will tackle four real-life scenarios and see why Terraform/Cloudformation is the better choice.
Scenario 1
A company is using multiple cloud providers (AWS, Microsoft Azure, and Google Cloud) and also wants to manage everything related to their GitHub organization through an IaC tool.
For this scenario, if you want to use a single tool that can do everything you need (manage infrastructure from multiple cloud providers + GitHub resources), the only viable option between the two will be Terraform, as it has dedicated providers for all of the providers plus a dedicated provider for GitHub.
Scenario 2
A company is very invested in AWS, using a bunch of AWS services and requiring the most up-to-date integrations and features.
While, for this scenario, both Terraform and CloudFormation can be used, CloudFormation will have the upper hand as most features are included as soon as they are live into Cloudformation.
Scenario 3
A company needs to build hundreds of environments that have a similar template (just some variables change).
For this scenario, through the modules and the ability to take advantage of loops, conditionals, and a bunch of functions, Terraform is the winner.
Scenario 4
A company has a very complicated AWS Architecture that involves intricate IAM roles, VPC configurations, and direct connections, with a need for strict compliance and governance structures.
While both tools can work, AWS CloudFormation is more suited for the job, as Its direct integration with AWS services ensures that configurations adhere closely to AWS's recommended practices, making it easier to meet strict enterprise governance requirements.
Can Terraform and CloudFormation be used together?
You can use Terraform and AWS CloudFormation together, but it wouldn't be the smoothest workflow. Using them together might be considered in specific scenarios where their features complement each other or when transitioning from one tool to the other.
Terraform allows you to create CloudFormation stacks using the aws_cloudformation_stack resource, so calling the entire workflow from Terraform would make perfect sense. This is especially useful in environments where different DevOps or Platform teams prefer different tools due to their expertise or historical reasons.
Automating Infrastructure as Code with CloudFormation and Terraform
So by now, you know that you have a variety of infrastructure as code languages to choose from -- with the two most common being AWS CloudFormation and Terraform, but these tools all inevitably bring about new problems that can be difficult to solve.
Most organizations will initially go down the path of building their own custom tooling or scripts around their IaC deployments but will eventually discover that these custom-built tools often don't scale, meet compliance requirements, and require overhead to maintain. Not to mention the fact that if you're using multiple IaC languages, you'll have to build multiple tools yourself or further complicate the existing custom tool you're attempting to build.
Fortunately, there is a tool that can solve these types of problems -- and provide many additional benefits, such as compliance, reliability and scalability. Spacelift is the most flexible CI/CD tool for infrastructure as code and was purpose-built for this use case. Spacelift supports multiple IaC languages (including AWS CloudFormation and Terraform), which allows you to standardize your deployment processes and compliance requirements across all of your IaC languages. Additionally, Spacelift has many unique features, such as Policies -- which can be used for access controls, approvals, customizing your deployment workflows, and even creating dependencies across your IaC languages.
If you want to learn more about Spacelift, create a free account today or book a demo with one of our engineers.
Should you use Terraform over CloudFormation?
The battle of Terraform vs. CloudFormation is poised to be an ongoing debate. At the end of the day, this is a decision for you to make based on your preferences between the two tools.
If having native support from AWS is essential to you, then perhaps you should consider AWS CloudFormation. If you enjoy the dynamic features that Terraform provides, such as count
and for_each
, maybe Terraform is best.
Is Terraform better than CloudFormation?
Terraform is better than CloudFormation in many use cases, but at the same time, if your infrastructure is exclusively on AWS and you always need to have the latest updates for the different services you are using, or if you need to build really complex AWS architectures, CloudFormation can be a very sensible choice.
Key points
At the end of the day, though, why restrict yourself to simply one infrastructure-as-code tool if you are able to leverage the benefits of both? There's nothing wrong with using multiple infrastructure-as-code tools, especially if your IaC automation tool can support this.
If you want to learn how other tools compare to Terraform, see our Terraform vs. Kubernetes article and 10 popular Terraform alternatives.
Thank you for taking the time to read this blog post. I wish your team the best of luck in your infrastructure-as-code journey!
Written by Chris Spitzenberger and Flavius Dinu.