Writing CloudFormation templates becomes difficult to manage once you start using it heavily. Whether it is one complicated template or multiple simple templates, maintaining the templates are a decent amount of work. This post covers a tool I wrote called lono to that manages and generates CloudFormation templates.

This post is a continuation of: Why Generate CloudFormation Templates with Lono.

NOTE: All the source code for this post is available on Github: tongueroo/cloudformation-examples-lono.

How Lono Works

With lono, you compile CloudFormation templates from ERB ruby template. You specify the template variables in the lono template block. An example explains it best. We’ll build an example off of the tutorials from A Simple Introduction to AWS CloudFormation series.

Lono-ifying the Project

The original raw CloudFormation templates are available in the tongueroo/cloudformation-examples repo. There are 2 templates single-instance.yml and instance-and-route53.yml.

The new lono-ify version of the templates are available in tongueroo/cloudformation-examles-lono at templates/instance.yml.

Notice how the new template has an if ERB statement now: <% if @route53 %>. Here’s part of templates/instance.yml:

SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
<% if @route53 %>
  HostedZoneName:
    Description: The route53 HostedZoneName. For example, "mydomain.com."  Don't forget the period at the end.
    Type: String
  Subdomain:
    Description: The subdomain of the dns entry. For example, hello -> hello.mydomain.com, hello is the subdomain.
    Type: String
<% end %>

What you are looking at is a lono template view which lono will take with the variables declared in config/templates/base/stacks.rb and combined them to compile them down to a CloudFormation template in the outputs folder. Here’s the config/templates/base/stacks.rb contents:

template "single-instance" do
  source "instance"
end

template "instance-and-route53" do
  source "instance"
  variables(
    route53: true
  )
end

The overall process looks like this:

You then use the generated CloudFormation template just as if you would normally use a vanilla CloudFormation template because it is a vanilla CloudFormation template at that point.

Here’s the config/templates/base/stacks.rb file with the templates converted to smarter lono templates.

Lono generate

Let’s clone the project from GitHub and generate the CloudFormation templates from lono templates.

git clone https://github.com/tongueroo/cloudformation-examples-lono
bundle # to install the gem dependencies
bundle exec lono generate

You should see this output:

$ bundle exec lono generate
Generating both CloudFormation template and parameter files.
Generating CloudFormation templates:
  output/single-instance.yml
  output/instance-and-route53.yml
  output/asg.yml
Generating params files
Params file generated for asg at output/params/stag/asg.json
Params file generated for instance-and-route53 at output/params/stag/instance-and-route53.json
Params file generated for single-instance at output/params/stag/single-instance.json

The lono generate command generates the CloudFormation templates to the output folder using the config/templates/base/stacks.rb and templates/* files.

Launch the Stack

Let’s create the stack the same way we have been using in the Simple Introduction to AWS CloudFormation series except using the generated templates from lono in the output folder.

aws cloudformation create-stack --template-body file://output/single-instance.yml --stack-name single-instance --parameters ParameterKey=KeyName,ParameterValue=tutorial ParameterKey=InstanceType,ParameterValue=t2.micro

You can view the status of the stack in the CloudFormation console:

Note, that lono comes with it’s own lono cfn create command that we could have used, but I used the standard aws cloudformation CLI commands to demonstrate that the generated templates are vanilla CloudFormation templates. We can use these generated templates just as we would use any other CloudFormation template.

Cleanup After Yourself

Remember to clean up and delete the stack so you do not get charged more than you have to.

aws cloudformation delete-stack --stack-name single-instance

Summary

We have taken raw CloudFormation templates and converted it to a lono templates. With this in place, there is a solid foundation to be able to generate multiple CloudFormation templates and allow us to use conditional logic in the ERB templates. As mentioned in the Why Generate CloudFormation Templates with Lono Post, we were able efficiently managing over 250 CloudFormation stacks based on four main core templates with lono. It would have been impossible to manage all of those templates without some type of automation. If you have any questions about lono feel free to reach out. Hopefully, this has been helpful!

In the next post we’ll cover how we can use lono to generate a highly available autoscaling application tier CloudFormation stack: AutoScaling CloudFormation Template with Lono.