Any real time application is going to require more than 1 resource for its operation – for example a web application may require loadbalanced webservers, application server and a database server. Whenever you are going to deploy this application you need to manage all these resources separately. Imagine a case where there is a need to repeat the deployment multiple times. Few scenarios are,

A saas application running in a single tenant model

An enterprise application that needs to be deployed for multiple regions.

In the above scenarios the entire setup has to be launched and maintained multiple times. To simplify this process AWS has an impressive feature called  cloudformation.

In an AWS Migration, AWS CloudFormation enables you to create and delete related AWS resources together as a unit called a stack. The way it works is

You create a template which is a simple JSON format with the metadata of the resources required for your application.

Use this template further to create stacks which deploys the necessary resources for your application.

In the previous example we will be able to define a template called  “MyWebApplication” which contains the various resources required to create the web application and create stacks from it which would launch all the resources needed for the application.  Cloudformation is a free service and you will have to pay only for the resources created using the service.

Apart from the ability to create the resources cloudformation has few more interesting features. I am listing 2 of them below

Ability to automate installations

 Helper Scripts: AWS CloudFormation provides a set of Python helper scripts that you can use to install software and start services on an Amazon EC2 instance that you create as part of your stack. You can call the helper scripts directly from your template. The scripts work in conjunction with resource metadata that you define in the same template. The helper scripts run on the Amazon EC2 instance as part of the stack creation process. The scripts can also be installed on Microsoft Windows

using Python for Windows. The template can include calls to the helper scripts to install the packages. The main helper functions are

cfn-init: Used to retrieve and interpret the resource metadata, installing packages, creating files and starting services.

cfn-signal: A simple wrapper to signal a CloudFormation WaitCondition allowing you to

synchronize other resources in the stack with the application being ready.

cfn-get-metadata: A wrapper script making it easy to retrieve either all metadata defined for a resource or path to a specific key or subtree of the resource metadata.

cfn-init needs to be used conjuction with the Metadata section called “AWS::CloudFormation::Init”. This sections contains the metadata of Commands, Files, Services, Packages etc.that Cfn_Init uses to install

Example of cf_init section

cfn-init -s “, { “Ref” : “AWS::StackName” }, ” -r WebServer “,

”    –access-key “,  { “Ref” : “HostKeys” },

”    –secret-key “, {“Fn::GetAtt”: [“HostKeys”, “SecretAccessKey”]},

”    –region “, { “Ref” : “AWS::Region” }, ” || error_exit ‘Failed to run cfn-init’\n”,

Example of Metadata section of cf_init

 Metadata” : {

“AWS::CloudFormation::Init” : {

“config” : {

“packages” : {

“yum” : {

“gcc-c++”      : [],

“make”         : [],

……

},

 

“sources” : {

“/home/ec2-user/tracks” : “https://github.com/TracksApp/tracks/tarball/v2.0”

},

 

“files” : {

“/tmp/setup.mysql” : {

“content” : { “Fn::Join” : [“”, [

“CREATE DATABASE “, { “Ref” : “DBName” }, “;\n”,

 

“services” : {

“sysvinit” : {

“mysqld” : {

“enabled”       : “true”,

“ensureRunning” : “true”

}

}

}

}

}

},

Cloud Init: The latest Linux AMIs contain cloud-init, an open source program that automatically configures

and starts your applications according to a script that you provide. You can provide the scripts as a part of section in the template called UserData

example

“UserData” : { “Fn::Base64” : { “Fn::Join” : [“”,[

“#!/bin/bash -ex”,”\n”,

“yum -y install gcc-c++ make”,”\n”,

“yum -y install mysql-devel sqlite-devel”,”\n”,

“yum -y install ruby-rdoc rubygems ruby-mysql ruby-devel”,”\n”,

………

 

]]}}

 

Ability To Wire AutoScale Parameters

As a part of the launch configuration of the instance you will be able to specify the auto scale up and down parameters and also the alarm cloud watch parameters. If not for this the same configuration should have been done and maintained in 3 different places

Example,

“Resources” : {

“WebServerGroup” : {

“Type” : “AWS::AutoScaling::AutoScalingGroup”,

“Properties” : {

“AvailabilityZones” : { “Fn::GetAZs” : “”},

“LaunchConfigurationName” : { “Ref” : “LaunchConfig” },

“MinSize” : “1”,

“MaxSize” : “3”,

“LoadBalancerNames” : [ { “Ref” : “ElasticLoadBalancer” } ]

}

},

“LaunchConfig” : {

“Type” : “AWS::AutoScaling::LaunchConfiguration”,

“Properties” : {

“KeyName” : { “Ref” : “KeyName” },

“ImageId” : { “Fn::FindInMap” : [ “AWSRegionArch2AMI”, { “Ref” :

“AWS::Region” },

{ “Fn::FindInMap” : [ “AWSInstance

Type2Arch”, { “Ref” : “InstanceType” },

“Arch” ] } ] },

“UserData” : { “Fn::Base64” : { “Ref” : “WebServerPort” }},

“SecurityGroups” : [ { “Ref” : “InstanceSecurityGroup” } ],

“InstanceType” : { “Ref” : “InstanceType” }

}

},

“WebServerScaleUpPolicy” : {

“Type” : “AWS::AutoScaling::ScalingPolicy”,

“Properties” : {

“AdjustmentType” : “ChangeInCapacity”,

“AutoScalingGroupName” : { “Ref” : “WebServerGroup” },

“Cooldown” : “60”,

“ScalingAdjustment” : “1”

}

},

“WebServerScaleDownPolicy” : {

“Type” : “AWS::AutoScaling::ScalingPolicy”,

“Properties” : {

“AdjustmentType” : “ChangeInCapacity”,

“AutoScalingGroupName” : { “Ref” : “WebServerGroup” },

“Cooldown” : “60”,

API Version 2010-05-15

“ScalingAdjustment” : “-1”

}

},

“CPUAlarmHigh”: {

“Type”: “AWS::CloudWatch::Alarm”,

“Properties”: {

“AlarmDescription”: “Scale-up if CPU > 90% for 10 minutes”,

“MetricName”: “CPUUtilization”,

“Namespace”: “AWS/EC2”,

“Statistic”: “Average”,

“Period”: “300”,

“EvaluationPeriods”: “2”,

“Threshold”: “90”,

“AlarmActions”: [ { “Ref”: “WebServerScaleUpPolicy” } ],

“Dimensions”: [

{

“Name”: “AutoScalingGroupName”,

“Value”: { “Ref”: “WebServerGroup” }

}

],

“ComparisonOperator”: “GreaterThanThreshold”

}

},

“CPUAlarmLow”: {

“Type”: “AWS::CloudWatch::Alarm”,

“Properties”: {

“AlarmDescription”: “Scale-down if CPU < 70% for 10 minutes”,

“MetricName”: “CPUUtilization”,

“Namespace”: “AWS/EC2”,

“Statistic”: “Average”,

“Period”: “300”,

“EvaluationPeriods”: “2”,

“Threshold”: “70”,

“AlarmActions”: [ { “Ref”: “WebServerScaleDownPolicy” } ],

“Dimensions”: [

{

“Name”: “AutoScalingGroupName”,

“Value”: { “Ref”: “WebServerGroup” }

}

],

“ComparisonOperator”: “LessThanThreshold”

}

},

“ElasticLoadBalancer” : {

“Type” : “AWS::ElasticLoadBalancing::LoadBalancer”,

“Properties” : {

“AvailabilityZones” : { “Fn::GetAZs” : “” },

“Listeners” : [ {

“LoadBalancerPort” : “80”,

“InstancePort” : { “Ref” : “WebServerPort” },

“Protocol” : “HTTP”

} ],

“HealthCheck” : {

“Target” : { “Fn::Join” : [ “”, [“HTTP:”, { “Ref” : “WebServerPort” },

“/”]]},

“HealthyThreshold” : “3”,

API Version 2010-05-15

46

AWS CloudFormation User Guide

Auto Scaling Group with LoadBalancer, Auto Scaling

Policies, and CloudWatch Alarms

“UnhealthyThreshold” : “5”,

“Interval” : “30”,

“Timeout” : “5”

}

}

},

“InstanceSecurityGroup

In the coming blogs let us look at the other cool features of AWS