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.
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.
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:
Some of the other characteristics of Terraform:
Some of the characteristics:
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 (
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):
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
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
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:
Some characteristics:
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 (
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:
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:
The
There are others, with a very specific focus, such as Ruby On Jets.
On a lower level of abstraction are
They provide excellent improvements over the raw CloudFormation, in some cases extending to the full multi-environment, multi-stack solutions.
Also the improvements the AWS SAM bring the CloudFormation templates to a little bit higher level.
The
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
References to the tools in this article:
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
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
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)
- 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)
- 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
- 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
andTypeScript
- a large number of
nodejs
dependencies
- 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
- 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
- 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
- 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: