In the last CloudFormation post, Generating CloudFormation Templates with Lono, the stack was intentionally designed simple to allow focus on learning and understanding CloudFormation basics. The stack was not that useful in real life. Today, I’ll walk through a CloudFormation template that is practical and useful for real life use cases: an AutoScaling App Tier.

Note, all the source code for this post is available on Github: tongueroo/cloudformation-examples-lono.

Why an AutoScaling App Tier

An AutoScaling App Tier is an extremely useful stack because it is the standard stack to which you can deploy and run application code.

One of my first thoughts of when I first learned of EC2, AutoScaling and CloudFormation was: Why not just launch a fleet of EC2 servers and not bother with AutoScaling? It’s more work to figure out AutoScaling and I just want to get servers up and running fast. I was hesitant to take on learning AutoScaling for time concerns.

It turns out that AutoScaling is amazingly simple and quick to setup with CloudFormation. It is so simple you have little reason not to use this as the default stack to run applications. Apps should always be on an AutoScaling tier. Once you get on Autoscaling you get all of these benefits:

  • Ensures a highly availability of infrastructure.
  • Applications will self-heal. Servers will be “Cows not Pets”
  • If there’s a weird one off instance that is misbehaving, AutoScaling will terminate it and replace it automatically. Robots can do mechanical things like this faster than humans.
  • Provides infrastructure scaling knobs to adjust if needed.

Build AutoScaling CloudFormation Template

There is little point in starting the CloudFormation template from scratch. So let’s head over to the official AWS CloudFormation sample templates and grab the Load-based auto scaling sample template.

curl -o asg.json https://s3.amazonaws.com/cloudformation-templates-us-east-1/AutoScalingMultiAZWithNotifications.template

Understanding the Template

Let’s take a look at the resources defined in the downloaded template:

$ cat asg.json | jq -r '.Resources[].Type' | sort | uniq -c | sort -n
   1 AWS::AutoScaling::AutoScalingGroup
   1 AWS::AutoScaling::LaunchConfiguration
   1 AWS::EC2::SecurityGroup
   1 AWS::ElasticLoadBalancingV2::Listener
   1 AWS::ElasticLoadBalancingV2::LoadBalancer
   1 AWS::ElasticLoadBalancingV2::TargetGroup
   1 AWS::SNS::Topic
   2 AWS::AutoScaling::ScalingPolicy
   2 AWS::CloudWatch::Alarm
$

Let’s also look at the Parameters:

$ cat templates/asg.json | jq -r '.Parameters | keys[]'
InstanceType
KeyName
OperatorEMail
SSHLocation
Subnets
VpcId
$

It would be nice to only see the Parameters that do not contain default values and are required. You can use this jq expression to see that:

$ cat templates/asg.json | jq -r '.Parameters | to_entries[] | {name: .key, default: .value.Default} | select(.default == null) | .name'
VpcId
Subnets
OperatorEMail
KeyName
$

Okay, so now we have an excellent idea of what is required to make this template work.

Lono CloudFormation Template Changes

I prefer to work with CloudFormation with YAML, so I’ll convert the template to YAML before taking advantage of using lono to clean up the template further.

$ ruby -ryaml -rjson -e 'puts YAML.dump(JSON.load(ARGF))' < asg.json > templates/asg.yml

I cleaned up asg.yml.erb the template by moving the scripts to lono partials:

Moving the scripts into these lono partials makes them a ton easier to read.

Let’s add the lono template definition to config/templates/base/stacks.rb:

template "asg"

Now we can run lono generate to create the output template file. The output should look similar to this:

$ bundle exec lono generate
Generating CloudFormation templates:
  output/asg.yml
$

Launch the Stack

Okay, now that we’ve downloaded the template, updated it to use lono and generated the templates to the output folder, we can get ready to launch the stack.

Let’s build up the params file that is required. I’m using the default VPC and default subnets to keep things simple, but you can use any VPC and subnet you would like. Here’s the params/asg.txt parameter file:

KeyName=tutorial
InstanceType=t2.micro
OperatorEMail=tung@boltops.com
VpcId=vpc-427d5123 # NOTE: use your own VPC Id
Subnets=subnet-36f48123,subnet-f0a83123,subnet-b2c52123

Note these the VpcId and Subnets values need to be change for your AWS account.

Let’s create the stack now!

bundle exec lono cfn create asg

You can check the status of the stack on the CloudFormation console. You should see something like this:

The stack with all the resources: AutoScalingGroup, LaunchConfiguration, SecurityGroup, Listener, LoadBalancer, TargetGroup, SNS::Topic, 2 ScalingPolicies and 2 CloudWatch::Alarms, took only 4 minutes to create.

Confirm CloudFormation Stack Working

Check the ELB endpoint to see if the stack is up and running. Note that I had to open port 80 to the world on the ELB’s security group. You should see a simple html page like this:

Congratulations, you have successfully create an extremely valuable CloudFormation App AutoScaling Tier stack. I have found that this is one of the most commonly used stacks in real life.

In the next post, I’ll cover lono, a tool that makes the process described in this post even more simple: Easily Manage CloudFormation Templates with lono cfn.