Terraform vs CloudFormation

Roman Krivtsov
Jan 9 · 3 min read

Infrastructure as Code is an approach to describe and manage on-premise or cloud resources. There are 2 types of IaC tools:

  • configuration management tools (Ansible, Chef, Puppet)
  • orchestration (Terraform, CloudFormation)

Configuration management tools are aimed at modifying the existing infrastructure, which is close to the procedural approach. Some of the configuration tools are also overlapped with orchestration.

Orchestration tools work declaratively. They describe the infrastructure and keep its state.

If a change is not applicable by orchestration tool (e.g some settings of EC2 instances or DynamoDB indexes with existing data), it may require complete recreation of the resource and it’s possible because it keeps the entire configuration of the infrastructure.

In this article we consider Terraform and CloudFormation as orchestration tools.


Terraform is IaC engine which allows you to unfold your infrastructure on various types of providers: On-premise, AWS, Azure, Google, Kubernetes, etc. At the same time, some of the concrete services from some providers might be not supported or verified by Terraform.

Download and install Terraform https://www.terraform.io/downloads.html

If you are going to use Terraform for AWS deployment, you have to configure it. Create a main.tffile

    region                  = "eu-central-1"    profile                 = "thinkport"}

Now Terraform will apply all operation on behalf of your AWS named account. Sometimes it’s worth it to create a separate user for Terraform only.

Terraform uses its own scripting language called HashiCorp Configuration Language (HCL), which allows to apply some additional programming logic (variables, mapping, conditions etc.) inside your template and keep the configuration laconic.

Resources are described in the resourcesection. That’s how for example will look creating of S3 bucket:

    region                  = "eu-west-3"    profile                 = "thinkport"}    resource "aws_s3_bucket" "terraform_test" {    bucket = "thinkport-terraform-test"}

Where aws_s3_bucket is a resource type, terraform_test — resource name and everything inside of curly braces are arguments or resource properties.

Running terraform planyou will see what Terraform is going to perform.

terraform apply will run your template.

To delete resources created by TF template, run terraform destroy

It’s possible to pass variables to the template and get certain outputs.

For better granulation you might want to split you big template into several parts. It’s possible with Terraform modules.

There is a way to integrate Terraform with configuration management tools, using Provisioners, for example to run some commands on newly created EC2 instance.

By default Terraform stores the state (and the history of all the state changes) locally. It’s possible and recommended to organize a remote state storage for better team work, e.g via S3 or file hosting service.

Remote state management with remote backends is available only in Enterprise version.

Terraform doesn’t support automatic rollbacks, so if the change leads to unwanted consequences you must apply the previous state manually.


CloudFormation is a native AWS service and tool for orchestrating AWS resources. It officially supports most of the AWS services and their configurations.

If you have AWS CLI already installed you can start using CloudFormation.

CloudFormation uses JSON or YAML for writing templates which make it sometimes quite verbose.

Let’s create a simple deployment with template.yaml:

Resources:  TestS3Bucket:    Type: AWS::S3::Bucket    Properties:      BucketName: 'roman-terraform-test'

And then run

aws cloudformation --profile thinkport --region eu-central-1 deploy --stack-name=testStack --template-file ./template.yaml

To monitor the process of creation and review the result you go to CloudFormation UI https://eu-central-1.console.aws.amazon.com/cloudformation and select your stack (testStack)

CloudFormation also can accept variables called Parameters from the CLI and also generate Outputs.

CloudFormation uses notion Stack for defining a piece of infrastructure. Each Stack uses one template file. It’s recommended to split your infrastructure to logical parts for composition, better reading and easier deployment.

Once you delete the Stack, all the resources from the appropriate template are gone.

If the change of a resource caused an error, CF will trigger rollback automatically.

aws cloudformation deployuploads the template automatically to S3, substituting needed variables and normalizing the template. The state of the stack is stored inside of Cloudformation service.

One of the often cases with IaC — manual changes in the infrastructure which can cause problems and inconsistencies. CloudFormation supports Drift Detection, which can be requested for a certain Stack to see whether there were changes in resources not defined in the Stack’s template.

Both approaches have it’s advantages and disadvantages, so choose what fits better for your purposes and have a good clouding!

Find me in Twitter

Roman Krivtsov

Written by

Cloud Architect at thinkport.digital. AWS, Big Data, DevOps