paint-brush
Your Infrastructure as Code šŸŒ© CloudFormation Vs Terraform?ā€‚by@nathanmalishev
42,194 reads
42,194 reads

Your Infrastructure as Code šŸŒ© CloudFormation Vs Terraform?

by [email protected]June 7th, 2018
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Imagine if all of your infrastructure configurations from AWS, Azure or Google could be replicated <strong>faster and more accurately than you could click</strong>. This is infrastructure as code.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coins Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Your Infrastructure as Code šŸŒ© CloudFormation Vs Terraform?
nathan.malishev@gmail.com HackerNoon profile picture

Imagine if all of your infrastructure configurations from AWS, Azure or Google could be replicated faster and more accurately than you could click. This is infrastructure as code.

The insane benefits of using infrastructure as code are:

  • Being able to sleep at night, knowing you can redeploy to a given state safely. If god forbid your infrastructure vanishes
  • Follow coding best practices, check in changes, code review and build your infrastructure as a team

I am going to be taking a look at both Terraform & CloudFormation. I used Terraform extensively at Localz but for the sake of learning I decided to get my hands dirty with CloudFormation.

The two contenders

Terraform is the communities answer to infrastructure as code. It is open source with over 12k stars, is cloud agnostic supporting hundreds of providers. It is often less verbose than CloudFormation & has a great module system.

CloudFormation is developed and maintained by AWS, it is very tightly integrated and only supports AWS. The tight integration lends itself to having a great UI, being able to view all your stacks for a given account is great. It enables cross stack referencing with ease, which is also a massive win for modularity and breaking down that monolith.

Command Line Interface & WorkĀ flow

Terraformā€™s most used command feature [init](https://www.terraform.io/docs/commands/init.html) and [plan](https://www.terraform.io/docs/commands/plan.html). Since Terraform is cloud agnostic you need to explicitly say where you will store your state file, this is a part of the init command. Running a Terraform plan is used to create an execution plan, against your state file and existing infrastructure.

A simple Terraform execution plan

CloudFormation has a similar process where you create & execute change sets. You will use a combination of [create-change-set](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-change-set.html)Ā , [execute-change-set](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/execute-change-set.html) and [deploy](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html). create-change-set is akin to Terraformā€™s plan whilst execute-change-set is Terraformā€™s apply & deploy rolls both commands into one.

The main difference is you will be looking at and resolving issues through CloudFormationā€™s UI, which is easy to use, even for me šŸ˜ƒ.

CloudFormationā€™s ChangeĀ set

Both Terraform's plan & CloudFormationā€™s create-change-set is a great place to have a manual check, in your continuous integration pipeline.

Using Gitlab to wait on a manual inspection of the changeĀ set

I found CloudFormations APIā€™s to be a little confused. I believe create-change-set followed by a execute-change-set used to be the de facto but now deploy exists to replace them both. But in some cases especially deploying to production, you would want to follow good practice and inspect the execution plan before you executing it.

I thought in this case you would want to use a create-change-set followed by a execute-change-set but that is annoying as create-change-set explicitly needs to know whether you are creating or updating stack. So this would cause heartache in your continuous integration pipelines. But after further inspection, I believe you run a deploy with a --no-execute-change-set flag, and then re run deploy without the flag. Iā€™m still unsure of the recommended approach.

Misaligned State

I ran a simple experiment where both tools created a simple EC2 instance. I deleted both instances and tried to run both deployment steps again.

Hidden within Terraformā€™s plan is a [refresh](https://www.terraform.io/docs/commands/refresh.html) which is used to reconcile your state file, with the real world infrastructure. This means Terraform was able to detect the deletion & boot up a new instance. CloudFormation has no such reconciliation and depends on the existing stack. Thus it was adamant nothing had changed. The only fix for CloudFormation was to rename the EC2 resource.

I wouldnā€™t rely on this as a silver bullet for reconciliation and wouldnā€™t ever recommend manually playing with any stacks, that are managed by any tool. It will only lead to heartbreak šŸ’”.

Functions & Interpolation

Intrinsic functions is one of my favourite parts of CloudFormation. Terraform does have a lot more functions than CloudFormation, but I prefer the syntax that CloudFormation uses, the lack of quotations, dollar signs & curly braces can make for some more readable code.

I also found the occasional shortcomings of Terraformā€™s interpolation in certain circumstances.

A simple referencing comparison

Conditional Deployments

Conditional deployments are an important part of any deployment, you want to be deploying from the same stack whether its production or development. But sometimes production just requires extra resources, or vice versa.

Only CloudFormation supports conditionals explicitly, you can tag each resource with a conditional flag. Where as Terraform requires you to make use of their (awesome) count parameter and ternary conditional.

The count parameter is unique to Terraform, so CloudFormation would require more repeated code.

Conditionals Example

CrossStack Referencing

One of CloudFormations most powerful features is being able to so easily cross stack reference. This makes it extremely easy to break up the infrastructure monolith!

Cross stack referencing is aĀ breeze

In the above example, the Networking Stack exports its DbSubnet1, as ${branch}-DbSubnet1. Which in my EC2 Stack I simply reference that Subnet using the Fn::ImportValue:Ā !Sub ${branch}-DbSubnet1Ā . CloudFormation is also smart enough to know that the EC2 stack relies on the Networking Stack and will refuse to delete it until its dependencies are gone.

Modules

Exclusive to Terraform modules are a very powerful way to break down your Terraform deployments. A Terraform module is essentially a collection of Terraform files & resources that define a set piece of infrastructure. It allows for inputs & outputs. To use the module, you simply pass in your inputs as variables and under the hood Terraform will pull in the module and execute the Terraform code as usual.

Reuse of a terraform module

Above is an example, where I define many instances in any region by simply using a reusable module. Without this module, I would need to define each instance and the associated Terraform code required to set up an instance in a new region.

The reason why this is not the same as a CloudFormation stack cross reference, is that the Terraform state file would still contain all of the state. Where as with CloudFormation, the state files would be split between each stack making it more manageable.

CloudFormation uses nested stacks to accomplish the same task. The issue with nested stacks are that if a child stack fails the entire stack will. This makes for deployment pains & nightmares. Approaching CloudFormation using a layered cake approach and cross stack referencing is the way to go.

CloudFormation with a nestedĀ stack

CloudFormation nested stack webĀ UI

User Data & CloudFormation Init

CloudFormation also features CloudFormation init, which is AWSā€™s way of taking your user data script and turning it into state based configuration. It is extremely powerful and shouldnā€™t be overlooked. It allows you to run stack updates against instances and reconcile the state. Where as previously using user data you would have to terminate and create a new instance.

A slice of CloudFormation Init

Error Handling

Maybe I was never very good at Terraform, but I have been preferring the way CloudFormations handles errors. The CloudFormation UI is really good and gives a good overview of your stack. I found that with Terraform errors, while they pointed you in the right direction it was still hard to gain an overall idea of what had happened.

The CloudFormation Events UI traces your stack deployment, so you can easily see what errorā€™dĀ out.

Support

You would think CloudFormation would support every AWS feature in existence, but unfortunately you are wrong. Because open source is the best, Terraform seems to have more AWS features.

Take for example, RDS with IAM auth, this feature has been released for over a year and is still in the CloudFormation backlog. Where as Terraform had a contributor gazoakley, make a simple PR and Terraform supports RDS IAM auth well before CloudFormation.

Another more important example, there is no Key Secrets Manager CloudFormation support. Where as terraform has its own resources for secrets manager since April.

Open source software is myĀ favorite

We canā€™t forget that Terraform is cloud agnostic, a big win. But I wouldnā€™t take it too literally as from what I have seen cloud providers are pretty good at sinking their tiny hooks into you through features, or specific codes like ARNs.

But because Terraform is cloud agnostic, it can really be applied to anything that has state and an API. For example Kong API Gateway can be managed with Terraform. Thus you can apply your skills youā€™ve learnt else where in your stack!

Summary

I enjoy both Terraform & CloudFormation as they are both a great step in the right direction.

My Pros &Ā Cons

CloudFormation has a great UI for both debugging and general overview of everything thats happening. Cross referencing is powerful & makes separating stacks easy, whilst I personally really enjoy the syntax. The lack of support is my real gripe, as itā€™s not open source the thought of having to use custom resources or shell scripts to get certain features makes me cringe. šŸ˜¢

Terraform is great because of itā€™s vibrant community of open sources, itā€™s simple module paradigm & itā€™s cloud agnostic. Terraform can be hard to debug through the cli and often you end up with a large monolith repo that includes all of your infrastructure. You can break it down into modules, but it doesnā€™t quite have the same separation of concerns you can get with CloudFormation.

Thanks for reading! If you enjoyed it be sure to give it a clap and check out both Terraform & CloudFormation!