AutoScaling CloudFormation Template with Lono

Tung Nguyen
BoltOps

--

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 really been useful in real life. Today, I’ll walk through a CloudFormation template that is extremely 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 a 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 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 really 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 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 a very good 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/lono.rb:

template "asg.yml" do
source "asg.yml.erb"
end

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 parameters 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 parameters/asg.json parameter file:

[
{
"ParameterKey": "KeyName",
"ParameterValue": "tutorial"
},
{
"ParameterKey": "InstanceType",
"ParameterValue": "t2.micro"
},
{
"ParameterKey": "OperatorEMail",
"ParameterValue": "tung@boltops.com"
},
{
"ParameterKey": "VpcId",
"ParameterValue": "vpc-427d5123"
},
{
"ParameterKey": "Subnets",
"ParameterValue": "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! Remember to generate the CloudFormation templates using `lono generate` again if you have made changes. If you would like to have the templates continuously generate as you make changes, you can also run bundle exec guard, covered at Continuously Generate CloudFormation Templates with Lono and Guard.

$ bundle exec lono generate
$ aws cloudformation create-stack --stack-name asg --template-body file://output/asg.yml --parameters file://parameters/asg.json

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.

Thanks for reading this far. If you found this post useful, I’d really appreciate it if you recommend this post (by clicking the clap button) so others can find it too! Also, connect with me on LinkedIn.

P.S. Be sure to join the BoltOps newsletter to receive free DevOps tips and updates.

--

--