AWS infrastructure tools comparison

Whether you need to run your side hustle or you are working in an enterprise environment, you probably want to deploy and maintain the applications and services using Infrastructure as code.
It is a de-facto standard today, especially with so much push towards cloud-based and serverless infrastructure.

There are numerous tools helping with that and it could be quite daunting to choose the best one for your needs.

In this post, I will look at some of the more popular options that I came around and describe which one might be a better tool for a given job.

Unfortunately, there is no "perfect" one and all of them have pros and cons.

Types of tools

There are 2 main categories of how the resources are created:
  • via API
  • via CloudFormation
The CloudFormation is the assembly of the AWS infrastructure. Whether you like it or not, it is pretty much guaranteed you'll have to deal with it at some stage.

API provisioning is being used less and less due to the robust CloudFormation support by AWS.

The API-based solutions also present non-trivial challenges of making sure the resources are correctly compared and updated.

For that reason, the API is mostly used for administration purposes or by the application to interact with the resources. Less so for provisioning.

Having said that, there are many other hosting companies that do not have an experience similar to CloudFormation.
The only way to achieve infrastructure as code in that case - using the API.

Terraform

Terraform is by far the most popular choice for the API-based provisioning.
It almost becomes and assembly of a general provisioning because it is not directed at a particular cloud provider. Great choice for multi-cloud deployments but can easily replace the AWS CloudFormation too.
It is fairly low level, similarly to CloudFormation, but a lot more dynamic.
For example, some of the small things that Terraform enables us to do that is challenging with CloudFormation:
  • automatically approve provisioned SSL certificates
  • maintain resources that are not supported by CloudFormation (such as Cognito authentication flows, OAuth scopes etc)
  • code reuse through modules
It is very well received by the community (and is open source).

Some of the other characteristics of Terraform:
  • plan - see what will be changed before the actual update
  • a "current state" of a Terraform project needs to be kept somewhere (as opposed to CloudFormation where AWS owns it)
  • when the changes are applied, they are blocking - the machine running those should not be stopped as the full change may not complete
  • taint-ed resources - instead of rollbacks (CloudFormation); Terraform marks the resources as tainted on failure so that they can be resolved/recreated
  • trivial to update a single resource as opposed to the whole stack (CloudFormation)
Good use-cases could be:
  • as a replacement of CloudFormation as well as the CloudFormation generation tools - it strikes a good balance
  • for multi-cloud environments or hosting providers that provide API (e.g. Linode)
  • complementary to the existing CloudFormation based solutions where CloudFormation is becoming challenging

Raw CloudFormation

Do not discount the basic CloudFormation though. It is relatively simple to provision important bits of infrastructure using native CloudFormation with a couple small scripts. This becomes the building block for the whole AWS.

Some of the characteristics:
  • native AWS support - it's going to stick around for a while
  • no need to manage your own "current state"; AWS runs all the updates and manages rollbacks
  • easy to see all the resources that are provisioned together
  • low-level but very powerful (StackSets, Marketplace etc)
Good use-cases could be:
  • simple stacks
  • stacks that rarely change and need to survive time (such as networking)
  • more complex stacks that use advanced features but have a team and/or skillset to support it
  • remove dependencies on tools - if you are unable to keep up with the changes (such NodeJS, Ruby, Python libraries updates)

DSL-based CloudFormation generators

This set of tools use metaprogramming to make it easier to generate the CloudFormation templates. Both are Ruby-based - probably because Ruby is quite good for building such DSLs.

SparkleFormation provides a DSL as well as a set of command line tools to generate and apply CloudFormation templates.

It does not enforce much structure so it's fairly easy to make mistakes. The convention-based approach to naming the fields could be confusing for some people (key_name becomes KeyName; but you can also use KeyName). There are some other nuances that require getting used to.

However, it provides a number of primitives for code reuse and it is possible to leverage full Ruby language as well as share the code using SparklePacks.

The cfndsl on the other hand - is like a Touring-complete CloudFormation. It looks a lot more like CloudFormation than Ruby and seems like a very simple templating language with full power of Ruby.

An important difference to SparkleFormation, however, is that it is a lot more strict. The resources must conform to the actual AWS CloudFormation Resource Specification, making debugging a bit easier as it will give an early error if you get some properties wrong.

While the two options are great for generating templates, I am mostly seeing stack_master orchestrating those tools. It provides a complete solution to maintaining AWS resources in a very robust way.

Some of the characteristics of this approach (assuming a tool like stack_master is used):
  • a complete solution to manage multiple stacks
  • requires (at least some) Ruby knowledge
  • requires multiple Ruby dependencies
  • the convention-based approach can often be confusing
  • when used with SparkleFormation, there's some initial mental overhead of having an additional layer between CloudFormation and Ruby
Good use-cases:
  • single stacks that are more complex than raw CloudFormation
  • managing complex services with multiple stacks
  • multi-environment deployments
  • can be thought of as a default choice

Object-Oriented CloudFormation generators

This set of tools leverages a programming language to build a "tree" of resources and then "serialise" it producing the resulting CloudFormation template.
These tools can normally enforce correctness via language primitives and make it easy to reuse the code in a usual way any developer would know.

Troposphere is a Python-based library that has been around for a while and is quite robust. Unfortunately, I haven't been able to use it much, but I'm pretty sure it needs orchestration, similar to stack_master to be able to cross-link multiple stacks.
Although, it seems like that orchestration should be relatively easy to implement from Python on a per-project basis.

There is also a similar one for Go - GoFormation.

The new and notable tool is AWS CDK which Amazon is still building (preview as of now) to provide higher level Object-Oriented abstraction for defining AWS resources.

The main difference between Troposphere and AWS CDK is that CDK comes with a built-in library for defining resources easier.
For example, CDK includes the constructs for provisioning Fargate service, lambda with API Gateway.

AWS CDK also focuses on TypeScript as a language, which provides great developer experience due to the built-in documentation and editor integrations.

The AWS CDK team plans to embed the JavaScript engine with the full library, essentially making it available to other languages and platforms (C#, Java, Python, Ruby).

Some characteristics:
  • more developer than architect focused
  • great code reuse tools via native language (TypeScript)
  • an initial mental overhead of having an additional layer on top of CloudFormation
  • requires knowledge of nodejs and TypeScript
  • a large number of nodejs dependencies
Good use-cases:
  • single stacks that are more complex than raw CloudFormation
  • managing complex services with multiple stacks
  • dynamically provisioning multiple stacks and environments
  • multi-environment deployments
  • can be thought of as a default choice

AWS Amplify CLI

AWS Amplify CLI provides a very high level of abstraction generating most of the CloudFormation infrastructure for you. The key here is opinionated and the focus is on feature rather than infrastructure.

Some characteristics:
  • opinionated
  • a large number of nodejs dependencies
  • focus on the web or mobile apps
  • focus on supporting the AWS Amplify client library
  • focus on features of the application rather than infrastructure management
Good use-cases:
  • very standard web applications
  • prototyping and proof of concepts
  • multi-environment deployments

Serverless Framework

Serverless Framework (SLS for short) does one thing extremely well - deploying lambda functions and setting up how to invoke them.

The configuration for that in SLS is a few lines of code, while there are dozens of lines in CloudFormation and other tools.

One simple example: setting up CORS on the API Gateway. Trivial in SLS (cores: true), a large amount of code with every other tool.

It also allows using CloudFormation format as part of its own configuration. But the templates only support basic "interpolation" and not as powerful as other options described here.

Some characteristics:
  • excels at deploying lambdas and linking it to different sources
  • less powerful for managing complex CloudFormation
  • no orchestration between multiple stacks (one CloudFormation per application)
  • a large number of nodejs dependencies
Good use-cases:
  • lambda based, single-stack applications
  • reasonably simple applications (architecturally-wise)

AWS SAM Templates

The AWS SAM Templates are just transformations that can be used with a regular CloudFormation.
They are a superset of the regular CloudFormation making it a lot easier to create Serverless Functions (somewhat similar to SLS).

Being an "extension" to the CloudFormation, it can be used with any of the generator tools listed here and can be very useful saving a lot of typing and giving the right defaults.

Some characteristics:
  • good improvement on top of CloudFormation for lambdas
  • very powerful for managing complex CloudFormation-s
  • comes with all the same characteristics of a regular CloudFormation
Good use-cases:
  • same as regular CloudFormation
  • good amount of serverless (lambdas with triggers) in the stack
  • when used in conjuntion with AWS SAM (including local development)

Summary

We looked at some of the tools I've been coming across and hope this helps you choose the best one for your project(s).

The Amplify and Serverless Framework are probably the best to get started quickly, for prototyping or applications that aren't very complex. They are sitting at the highest level of abstraction.
There are others, with a very specific focus, such as Ruby On Jets.

On a lower level of abstraction are stack_master  (with SparkleFormation and cfndsl), Troposphere, GoFormation.
They provide excellent improvements over the raw CloudFormation, in some cases extending to the full multi-environment, multi-stack solutions.

AWS CDK could be an excellent compromise between the very highly abstract tools and making it possible to customise your application/services as much as CloudFormation allows.
Also the improvements the AWS SAM bring the CloudFormation templates to a little bit higher level.

The Terraform could be a go-to tool when the CloudFormation isn't sufficient (multi-cloud environments, resources that lack CloudFormation support). Alternatively, it could just replace the raw CloudFormation as it provides a much better experience overall that is closer to the stack_master and AWS CDK than the raw CloudFormation.

It wouldn't make much sense to mix most of these tools described here together (due to harder orchestration of multiple stacks).
However, it would certainly not be unreasonable to complement CloudFormation based tools with Terraform due to its use of APIs.


References to the tools in this article: