If you’ve spent any time in the land of DevOps over the last few years you will have no doubt heard of the term “Infrastructure as Code”… The idea of defining your infrastructure environment in source code so that it’s easier to track changes and manage versions over time.
Ever since 2011, AWS has had a tool to do just that called, “CloudFormation”, a “service that gives developers and businesses an easy way to create a collection of AWS resources and provision them in an orderly and predictable fashion.” (Taken from the original release announcement available here). Over a decade later, CloudFormation is still the heart of any solution I develop within the AWS cloud computing ecosystem and all of the projects I’ve delivered for customers over the last decade.
But, what is CloudFormation? How do you write it? edit it? version of it? deploy it?
Well, In today’s article, I’ll walk you through what AWS CloudFormation is and how to get started using it. In future articles, I’ll explore some more in-depth use cases including how to define your own custom resources, add logic and more.
So, What is CloudFormation?
At its core, AWS CloudFormation is a service that helps you model and set up your AWS resources so that you can spend less time managing those resources and more time focusing on your applications that run in AWS. It helps us achieve three main things when it comes to our AWS environment:
- Simplify Infrastructure management by centralising all our configuration settings, properties and resources into a single location.
- Quickly replicate our infrastructure by allowing us to reuse the same code to deploy multiple sets of the same environment for testing, QA or fail-over scenarios.
- Easily control and track changes to our infrastructure by allowing us to use traditional source control mechanisms such as git to perform version control.
All of this is to say it’s a great way to make managing your environment easier.
What is it made up of?
CloudFormation is broken up into three main parts:
- Stacks
- Change Sets
- Templates
TEMPLATES
At its core, a CloudFormation template is nothing more than a JSON or YAML formatted text file, typically with either a .json or .yaml file extension (however it doesn’t actually matter). CloudFormation uses these templates as blueprints for building out our AWS resources.
As an example, if we wanted to deploy a WordPress website we could define the web Server, SQL Server, Load Balancer, storage and firewall rules as resources within a CloudFormation template. We could then deploy all of those resources by using the template to deploy a CloudFormation Stack.
STACKS
A CloudFormation stack is the implementation of a CloudFormation template within an AWS Account. Continuing from our example above, we can deploy the “WordPress” template as a stack within an environment and the stack would provision and configure each of the resources defined within the template.
Should we want to have multiple instances of our WordPress environment (say one for each of our websites, or perhaps separate Dev/Production environments) we can simply deploy another cloudFormation stack using the same cloudFormation template. This would result in a second environment configured identically to the first.
Once we have our new WordPress environment deployed via a CloudFormation Stack we will eventually want to make changes to it (maybe increase the server size, or leverage a new SQL version). We can simply update our CloudFormation template with the relevant changes and update the running stack using a Change Set
CHANGE SETS
Let’s say we want to open up a new firewall port on our Web Server to allow a new WordPress plugin to work correctly, we can simply add the new rule to the already written CloudFormation Template. We can then use that template to update our running CloudFormation Stack.
When we perform the update, we can generate a Change Set which is a summary of our proposed changes to the stack. This allows us to see how our changes might impact our running resources before implementing them. This is especially helpful when performing changes to a large environment with multiple resources.
For example, if we wanted to add our firewall rule,, the change set would outline that we are simply adding a new rule to our security group. This is a fairly simple and straightforward change with little risk posed to our running workloads.
However, if instead of adding a firewall rule we wanted to leverage a new major PostgreSQL version within our RDS cluster… things would be quite different. In this situation you can perform an in-place upgrade of RDS and as such CloudFormation will instead create a new RDS cluster and then remove the old one. This would result in you loosing your current database unless you’ve already backed it up. By utilising the Change Set prior to applying the change to your CloudFormation Stack, we would see the need for the RDS cluster to be replaced before any potential damage/data loss occurs.
So how do I use it?
Let’s walk through an example of how we might deploy a simple S3 bucket using CloudFormation Templates, Stacks and Change Sets.
Firstly we need to write a CloudFormation Template that will deploy our new S3 Bucket. The Syntax of CloudFormation Templates and how to write them will be the topic of a future article, but for now we can simply use the YAML file below and save the file as exampleTemplate.yaml on our local machine.
AWSTemplateFormatVersion: ‘2010-09-09’
Description: Example CloudFormation Template
Resources:
S3Bucket:
Type: ‘AWS::S3::Bucket’
Properties:
BucketName: mysuperrandomanduniquebucketname55
Next we want to log into our AWS Management Console and browse to the CloudFormation Console for our region here (we’ll use ap-southeast-2 for our example) and click on “Create Stack”.
under “Specify template” we want to select “Upload a template file”, click “Choose file” and then select the exampleTemplate.yaml file on our local machine. AWS will upload the file and after a moment we can then click “Next”.
Here we need to give our new CloudFormation Stack a name which will make “exampleStack”. The Parameters section doesn’t have any parameters for us to define (we’ll cover parameters in the next article) so once we’ve defined the next we can go ahead and click “Next”.
Under “Configure Stack Options” there are no setting we need to change at this stage so we can simply click “Next”
And on the “Review exampleStack” page we can review all the settings we have defined and if we are happy with them we can go ahead and click “Create stack”.
Now we can see all the CloudFormation Stacks currently in this account and our new “exampleStack” being deployed. After a couple of moments we can see that CloudFormation has finished deploying our new S3 bucket and the deployment is complete.
Making a Change
Now that we have our S3 bucket deployed we would like to configure the AccessControl to the bucket.
Firstly we need to update our template to define the required Access Control we’d like applied to our S3 Bucket. below is the revised file which we’ll save over the top of our existing exampleTemplate.yaml file
AWSTemplateFormatVersion: ‘2010-09-09’
Description: Example CloudFormation Template
Resources:
S3Bucket:
Type: ‘AWS::S3::Bucket’
Properties:
AccessControl: Private
BucketName: mysuperrandomanduniquebucketname55
In our CloudFormation Management console we need to select the Stack we’d like to update and click the “Update” button at the top of the screen.
in the “Update Stack” screen we want to select “Replace current template” and “upload the template file” from our local machine like we did in the last section. Once it’s uploaded we can click “Next”.
because we’ve already named our stack there is nothing to do on the “Specify stack details” page, so we can go ahead and just click next.
We can leave the Stack configuration alone as well, so again we can just click “Next”
If we scroll down to the bottom of the next page we can see the “Change Set preview” section where (after a moment) CloudFormation will outline the changes that will occur if we proceed with our update. In our example we can see that our S3 bucket will be modified but not replaced (indicated by the False statement in the “Replacement” column). With this understanding in hand we can click “Update stack”.
And after a few moments we can see that CloudFormation has finished updating our S3 bucket with the requested changes.
And that’s it, we’ve written our first CloudFormation template, deployed a CloudFormation Stack with it and then updated the stack and validated the change set.
Conclusion
AWS CloudFormation is an integral part of AWS environments and can provide a great opportunity for automation, simplification and control if used correctly… and best of all it’s free to use (AWS only changes for the resources you deploy with Cloudformation not the service itself).
In future articles I’ll walk through the process of writing CloudFormation templates, how to break environments up into manageable pieces and co-ordinate changes across dozens of stacks. If there is anything specific you’d like to see covered in relation to CloudFormation please feel free to get in touch.