AutoScaling CloudFormation Template with Lono
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:
- templates/partial/user_data/asg.sh.erb
- templates/partial/cfn/cfn-hup.conf.erb
- templates/partial/cfn/cfn-auto-reloader.conf.erb
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.
Thanks for reading this far. If you found this article useful, I'd really appreciate it if you share this article so others can find it too! Thanks 😁 Also follow me on Twitter.
Got questions? Check out BoltOps.
You might also like
More tools:
-
Kubes
Kubes: Kubernetes Deployment Tool
Kubes is a Kubernetes Deployment Tool. It builds the docker image, creates the Kubernetes YAML, and runs kubectl apply. It automates the deployment process and saves you precious finger-typing energy.
-
Jets
Jets: The Ruby Serverless Framework
Ruby on Jets allows you to create and deploy serverless services with ease, and to seamlessly glue AWS services together with the most beautiful dynamic language: Ruby. It includes everything you need to build an API and deploy it to AWS Lambda. Jets leverages the power of Ruby to make serverless joyful for everyone.
-
Lono
Lono: The CloudFormation Framework
Building infrastructure-as-code is challenging. Lono makes it much easier and fun. It includes everything you need to manage and deploy infrastructure-as-code.