AWS CloudFormation has been an easy and worthwhile skill I have learned this last year. I’m particularly fond of YAML as you can leave comments (Not multi line 😢) in your templates. This is literally my first tip.
1. Comment up your template
As you progress as a developer you learn to be nice to your future self with comments. Comments in your code also seem to illicit compliments from peers about good code, that is a nice feeling! Your comments should have links to any documentation, Medium articles, or stack overflow questions. This is easy as AWS maintains mostly complete documentation about each service that can be used with CloudFormation. The documentation can be found here.
Comments in YAML simply start with a #
.
2. Think about different environments
I’ll talk more about parameters next but as a preface, each template should be able to take an environment variable. Unfortunately you can not write the parameter file in YAML but let’s take a look at a simple one with a parameter for a development environment.
Then, in your template you can define two critical things to make this useful. First, the parameter declaration with allowed and default values.
Second, a condition to make a variable that determines if this is a PROD
stack . or not.
This allows you to start naming resources based on the environment. Here is an example were we tag a route table inside a VPC with a description and environment.
And another one were I change the way a resource is named based on the results of the IsProduction
value.
3. Don’t reference other templates use parameters instead.
First, let’s reason why we would use multiple templates. I would say it’s to control template length and to help isolate responsibilities. For example, a template I have that makes a VPC and configures it with all the bells a whistles is nearly 600 lines long. The template that sets up my RDS instance in that VPC is also 600 lines long! I would love to give one of those away to a new team member to maintain. Hopefully they would have an easy time because of tip one.
CloudFormation has an intrinsic function that lets you import the value of an output from another template. I advise on not using this and just maintaining a more detailed parameter file. The reason is two fold.
First, when updating or deleting templates you can forget which templates are linked via this import statement. It can lead to more work as you have to make changes in other stacks.
Second, it lets you write a more re-usable template. Just like it’s important to re-factor functions to be as simple as possible with clear inputs and outputs it’s important to think of a template this way. If someone didn’t wan’t to use the ARN of the SSL cert you hard coded for you CloudFront distribution you could refactor so that the ARN has to be a variable in the parameter file. Then anyone could use the template and know exactly what info they need to provide.
Other tips
While those are my main three tips outside of my workflow I have some thoughts on workflow also. First, keeping your templates under source control is key. I know CloudFormation already keeps versions of your templates but having them in a CodeCommit bucket with an environment for each branch makes it easy to manage. You can also manually role back by switching branches if you need. My other tip is to use CloudFormation from your CLI. Here is the reference. The statements can be kind of verbose but just think of how much infrastructure you are creating!
That’s all, thanks for reading and feel free to correct or disagree with anything.