AWS CloudFormation vs Terraform

Infrastructure as code (IaC) is the method of managing the infrastructure of a cloud environment through config files rather than manual efforts. With the emergence of cloud computing as the primary source of infrastructure, IaC has become an important skill set for system engineers.

IaC has brought about significant improvements in terms of speed, testing, and managing of infrastructure in engineering teams. It has dramatically reduced redundancy because these config files can be stored as templates that can be reused and version controlled for future provisioning.

There are several tools out there for IaC management. In this article, we’ll compare two extremely popular tools—AWS CloudFormation and Terraform—and their workings in AWS provisioning by demonstrating an EC2 instance deployment example.

AWS CloudFormation

CloudFormation is an IaC service offered by AWS that allows you to provision and manage AWS resources such as EC2 instances and S3 buckets through code. CloudFormation code is written in JSON or YAML and offers numerous ready-made templates that can be tweaked for most use cases. You can deploy almost anything in AWS using CloudFormation, since AWS themselves maintain it.

Terraform

Terraform is an open-source IaC tool developed by Hashicorp. Its code is written in Hashicorp Configuration Language (HCL), a declarative language quite similar to JSON. Terraform supports IaC not just in AWS but other major cloud providers as well, thereby making it well-suited for multi-cloud infrastructure management.

Deployment using CloudFormation vs Terraform

Let's look at deploying an EC2 instance using CloudFormation and Terraform. This will shed light on the differences in syntax between the two and help you choose the tool that will better suit your engineering team in the long run.

CloudFormation

CloudFormation can be deployed from the console or the AWS Command Line Interface (AWS CLI). Either way, the code remains the same. Generate AWS credentials that contain sufficient permissions to deploy EC2 instances along with a key pair before starting to work with CloudFormation.

The code to deploy a sample EC2 instance using CloudFormation is as shown below:

AWSTemplateFormatVersion: 2010-09-09 
Description: CloudFormation-ec2-example

Resources:
WebAppInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0d5eff06f840b45e9
InstanceType: t2.micro
KeyName: key_aws
SecurityGroupIds:
- !Ref SecurityGroupExample

SecurityGroupExample:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join ["-", [cloudFormation, example]]
GroupDescription: "Allow SSH inbound and outbound traffic"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0

The first paragraph provides the template format version and the description of the template:

AWSTemplateFormatVersion: 2010-09-09 
Description: CloudFormation-ec2-example

The first line does not normally change. The second line should contain the description of your template for documentation purposes.

The second paragraph describes the AWS resources to be deployed:

Resources: 
WebAppInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0d5eff06f840b45e9 # The ImageID is valid only in us-east-1 region
InstanceType: t2.micro
KeyName: key_aws # Put your key-pair
SecurityGroupIds:
- !Ref SecurityGroupExample

As the code snippet suggests, an EC2 instance is deployed with the properties depending on the use case, such as Instance type, Image ID, or KeyName. The last two lines indicate a reference to the security group that needs to be attached to the EC2 instance, without which we would not be able to SSH into the instance.

Here’s the third paragraph:

  SecurityGroupExample: 
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join ["-", [cloudFormation, example]]
GroupDescription: "Allow SSH inbound and outbound traffic"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0

At the end of the second paragraph, there’s a reference to the security group. The above code snippet describes the security group properties like the name, description, and networking rules. For now, one rule has been added to allow SSH access from any IP.

We’ll be using AWS CLI to deploy the stack. The command to deploy is the following:

aws cloudformation deploy --template ec2.yaml --stack-name ec2-sample-stack

Terraform

The next step is to deploy a sample EC2 instance using Terraform. Take advantage of Terraform’s modularity to try and break down the code into as many files as possible. First, add the AWS provider support to the code so Terraform can connect with AWS. AWS credentials can remain the same locally, as seen in the CloudFormation deployment. To add the providers, create a providers.tf file in the directory and add the below code:

terraform { 
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.15.0"
}
}
}

Next, define some variables to be used throughout the deployment process. This way, if the requirements constantly change, it will be easy to make changes only at one place. Create a variables.tf file and add the below code:

variable "ami" { 
default = "ami-0d5eff06f840b45e9"
}

variable "instance_type" {
default = "t2.micro"
}

variable "region" {
default = "us-east-1"
}

variable "key_name" {
default="key_aws"
}

It is always good to store different resources in different files rather than define all of them in a single file. Now, let's define the security group to be attached to the EC2 instance. Create a security_groups.tf file and add the below code:

resource "aws_security_group" "terraform_ssh" { 
name = "terraform_ssh_access"

#Incoming traffic
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] #replace it with your ip address
}

#Outgoing traffic
egress {
from_port = 0
protocol = "-1"
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}}

Above, Terraform received the instruction to create a security group with a rule for SSH access. Finally, write the code to deploy an EC2 instance. Create an instance.tf file and add the below code:

resource "aws_instance" "ec2-terraform" { 
ami = var.ami
instance_type = var.instance_type
key_name = var.key_name
security_groups = ["terraform_ssh_access"]
tags = {
Name = "terraform-example"

}}

In the above code, create an EC2 instance with the values being picked from the variables.tf file.

Now deploy the code. In the directory where all the files are stored, initialize Terraform with the below command:

terraform init

Now that Terraform is initialized, you can check the changes being made using the below command:

terraform plan

To apply the infrastructure, run

terraform apply

The EC2 instance should be deployed now. To bring down the infrastructure, run

terraform destroy

The pros and cons of CloudFormation

CloudFormation offers certain benefits and drawbacks.

Pros of CloudFormation:

  • As an AWS-backed tool, it integrates best with AWS resources. Any newly released AWS service will always be supported by CloudFormation first.
  • There are no additional costs from AWS involved when using CloudFormation.
  • State files are automatically managed by AWS. Automatic rollback is supported in case of a failure in infrastructure deployment, and changes in state are automatically synced.

Cons of CloudFormation:

  • It’s limited to AWS infrastructure management and isn’t suitable for multi-cloud deployments.
  • While writing CloudFormation code in JSON, you cannot add comments, as JSON does not support them. This makes it unsuitable for shared use across teams. Also JSON and YAML inherently do not support looping or conditionals which make readability slightly difficult for developers.

The pros and cons of Terraform

Now let’s look at Terraform’s advantages and limitations.

Pros of Terraform:

  • It supports a plethora of cloud providers with the help of plugins. With multi-cloud IaC, the choice to use Terraform is a no-brainer.
  • HCL supports usage of variables, looping and conditional statements which makes it extremely easy to write code in a developer-friendly way. Code can be cleanly separated into different files.
  • Terraform IaC is easy to get started with, even when coming from a different cloud provider background, since it largely remains uniform. For example, someone experienced in GCP can easily work on AWS Terraform scripts.

Cons of Terraform:

  • Since Terraform does not officially belong to AWS, it uses REST APIs to deploy infrastructure, which means that future AWS services will take time for Terraform to support.
  • The team must diligently manage state files. Failure to do so can lead to state errors due to conflicting changes, which can become difficult to debug.

CloudFormation vs Terraform Comparison Table

Terraform AWS CloudFormation
1. Terraform has multi-cloud IaC support. 1. CloudFormation only supports IaC for AWS.
2. It relies on APIs to deploy infrastructure and will take slightly longer before it supports new releases of AWS services. 2. AWS maintains CloudFormation, so it provides faster support for newly released AWS services and is suitable if the enterprise uses only AWS.
3. Terraform code is written in HCL, a declarative language created by Hashicorp. 3. CloudFormation is written in YAML or JSON.
4. Engineers need to manage the State files.They’re responsible for making sure it doesn’t get corrupted in case of conflicting changes. 4. AWS manages the State files in CloudFormation as a service. Engineers don’t have to worry about state files becoming corrupt.
5. Code supports using variables,looping and conditionals which makes it highly developer-friendly. 5. YAML or JSON do not support looping and conditionals, and as such are not very developer-friendly.

Conclusion

In this article, we have compared CloudFormation and Terraform and provided examples for deploying EC2 instances with each platform. Based on what we have observed, CloudFormation appears to be the better option of the two for infrastructure which is deployed exclusively on AWS, given the existing support by AWS that all but guarantees the best performance.

Was this article helpful?
Monitor your AWS environment

AWS Monitoring helps you gain observability into your AWS environment

Related Articles

Write For Us

Write for Site24x7 is a special writing program that supports writers who create content for Site24x7 "Learn" portal. Get paid for your writing.

Write For Us

Write for Site24x7 is a special writing program that supports writers who create content for Site24x7 “Learn” portal. Get paid for your writing.

Apply Now
Write For Us