{"id":821,"date":"2023-03-14T15:24:00","date_gmt":"2023-03-14T09:54:00","guid":{"rendered":"http:\/\/blog.aspiresys.com\/?p=821"},"modified":"2025-07-24T11:40:08","modified_gmt":"2025-07-24T06:10:08","slug":"aws-cool-feature-cloud-formation","status":"publish","type":"post","link":"https:\/\/www.aspiresys.com\/blog\/cloud\/cloud-adoption\/aws-cool-feature-cloud-formation\/","title":{"rendered":"AWS Cool Feature : Cloud Formation"},"content":{"rendered":"<p>Any real time application is going to require more than 1 resource for its operation &#8211; 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,<\/p>\n<p>A saas application running in a single tenant model<\/p>\n<p>An enterprise application that needs to be deployed for multiple regions.<\/p>\n<p>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\u00a0 cloudformation.<\/p>\n<p>In an <a href=\"https:\/\/www.aspiresys.com\/aws-migration-services\/\"><span style=\"text-decoration: underline;\"><strong>AWS Migration<\/strong><\/span><\/a>, <strong>AWS CloudFormation<\/strong> enables you to create and delete related AWS resources together as a unit called a stack. The way it works is<\/p>\n<p>You create a template which is a simple JSON format with the metadata of the resources required for your application.<\/p>\n<p>Use this template further to create stacks which deploys the necessary resources for your application.<\/p>\n<p>In the previous example we will be able to define a template called\u00a0 \u201cMyWebApplication\u201d 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. \u00a0Cloudformation is a free service and you will have to pay only for the resources created using the service.<\/p>\n<p>Apart from the ability to create the resources cloudformation has few more interesting features. I am listing 2 of them below<\/p>\n<p><strong>Ability to automate installations<\/strong><\/p>\n<p><strong>\u00a0Helper Scripts:<\/strong> 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<\/p>\n<p>using Python for Windows. The template can include calls to the helper scripts to install the packages. The main helper functions are<\/p>\n<p><strong>cfn-init<\/strong>: Used to retrieve and interpret the resource metadata, installing packages, creating files and starting services.<\/p>\n<p><strong>cfn-signal<\/strong>: A simple wrapper to signal a CloudFormation WaitCondition allowing you to<\/p>\n<p>synchronize other resources in the stack with the application being ready.<\/p>\n<p><strong>cfn-get-metadata<\/strong>: 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.<\/p>\n<p>cfn-init needs to be used conjuction with the Metadata section called \u201cAWS::CloudFormation::Init\u201d. This sections contains the metadata of Commands, Files, Services, Packages etc.that Cfn_Init uses to install<\/p>\n<p><strong>Example of cf_init section<\/strong><\/p>\n<p>cfn-init -s &#8220;, { &#8220;Ref&#8221; : &#8220;AWS::StackName&#8221; }, &#8221; -r WebServer &#8220;,<\/p>\n<p>&#8221;\u00a0\u00a0\u00a0 &#8211;access-key &#8220;,\u00a0 { &#8220;Ref&#8221; : &#8220;HostKeys&#8221; },<\/p>\n<p>&#8221;\u00a0\u00a0\u00a0 &#8211;secret-key &#8220;, {&#8220;Fn::GetAtt&#8221;: [&#8220;HostKeys&#8221;, &#8220;SecretAccessKey&#8221;]},<\/p>\n<p>&#8221;\u00a0\u00a0\u00a0 &#8211;region &#8220;, { &#8220;Ref&#8221; : &#8220;AWS::Region&#8221; }, &#8221; || error_exit &#8216;Failed to run cfn-init&#8217;\\n&#8221;,<\/p>\n<p><strong>Example of Metadata section of cf_init<\/strong><\/p>\n<p><strong>\u00a0<\/strong>Metadata&#8221; : {<\/p>\n<p>&#8220;AWS::CloudFormation::Init&#8221; : {<\/p>\n<p>&#8220;config&#8221; : {<\/p>\n<p>&#8220;packages&#8221; : {<\/p>\n<p>&#8220;yum&#8221; : {<\/p>\n<p>&#8220;gcc-c++&#8221;\u00a0\u00a0\u00a0\u00a0\u00a0 : [],<\/p>\n<p>&#8220;make&#8221;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 : [],<\/p>\n<p>\u2026\u2026<\/p>\n<p>},<\/p>\n<p>&#8220;sources&#8221; : {<\/p>\n<p>&#8220;\/home\/ec2-user\/tracks&#8221; : &#8220;https:\/\/github.com\/TracksApp\/tracks\/tarball\/v2.0&#8221;<\/p>\n<p>},<\/p>\n<p>&#8220;files&#8221; : {<\/p>\n<p>&#8220;\/tmp\/setup.mysql&#8221; : {<\/p>\n<p>&#8220;content&#8221; : { &#8220;Fn::Join&#8221; : [&#8220;&#8221;, [<\/p>\n<p>&#8220;CREATE DATABASE &#8220;, { &#8220;Ref&#8221; : &#8220;DBName&#8221; }, &#8220;;\\n&#8221;,<\/p>\n<p>&#8220;services&#8221; : {<\/p>\n<p>&#8220;sysvinit&#8221; : {<\/p>\n<p>&#8220;mysqld&#8221; : {<\/p>\n<p>&#8220;enabled&#8221;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 : &#8220;true&#8221;,<\/p>\n<p>&#8220;ensureRunning&#8221; : &#8220;true&#8221;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p><strong>Cloud Init:<\/strong> The latest Linux AMIs contain cloud-init, an open source program that automatically configures<\/p>\n<p>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<\/p>\n<p>example<\/p>\n<p>&#8220;UserData&#8221; : { &#8220;Fn::Base64&#8221; : { &#8220;Fn::Join&#8221; : [&#8220;&#8221;,[<\/p>\n<p>&#8220;#!\/bin\/bash -ex&#8221;,&#8221;\\n&#8221;,<\/p>\n<p>&#8220;yum -y install gcc-c++ make&#8221;,&#8221;\\n&#8221;,<\/p>\n<p>&#8220;yum -y install mysql-devel sqlite-devel&#8221;,&#8221;\\n&#8221;,<\/p>\n<p>&#8220;yum -y install ruby-rdoc rubygems ruby-mysql ruby-devel&#8221;,&#8221;\\n&#8221;,<\/p>\n<p>\u2026\u2026\u2026<\/p>\n<p>]]}}<\/p>\n<p><strong>Ability To Wire AutoScale Parameters<br \/>\n<\/strong><\/p>\n<p>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<\/p>\n<p>Example,<\/p>\n<p>&#8220;Resources&#8221; : {<\/p>\n<p>&#8220;WebServerGroup&#8221; : {<\/p>\n<p>&#8220;Type&#8221; : &#8220;AWS::AutoScaling::AutoScalingGroup&#8221;,<\/p>\n<p>&#8220;Properties&#8221; : {<\/p>\n<p>&#8220;AvailabilityZones&#8221; : { &#8220;Fn::GetAZs&#8221; : &#8220;&#8221;},<\/p>\n<p>&#8220;LaunchConfigurationName&#8221; : { &#8220;Ref&#8221; : &#8220;LaunchConfig&#8221; },<\/p>\n<p>&#8220;MinSize&#8221; : &#8220;1&#8221;,<\/p>\n<p>&#8220;MaxSize&#8221; : &#8220;3&#8221;,<\/p>\n<p>&#8220;LoadBalancerNames&#8221; : [ { &#8220;Ref&#8221; : &#8220;ElasticLoadBalancer&#8221; } ]<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;LaunchConfig&#8221; : {<\/p>\n<p>&#8220;Type&#8221; : &#8220;AWS::AutoScaling::LaunchConfiguration&#8221;,<\/p>\n<p>&#8220;Properties&#8221; : {<\/p>\n<p>&#8220;KeyName&#8221; : { &#8220;Ref&#8221; : &#8220;KeyName&#8221; },<\/p>\n<p>&#8220;ImageId&#8221; : { &#8220;Fn::FindInMap&#8221; : [ &#8220;AWSRegionArch2AMI&#8221;, { &#8220;Ref&#8221; :<\/p>\n<p>&#8220;AWS::Region&#8221; },<\/p>\n<p>{ &#8220;Fn::FindInMap&#8221; : [ &#8220;AWSInstance<\/p>\n<p>Type2Arch&#8221;, { &#8220;Ref&#8221; : &#8220;InstanceType&#8221; },<\/p>\n<p>&#8220;Arch&#8221; ] } ] },<\/p>\n<p>&#8220;UserData&#8221; : { &#8220;Fn::Base64&#8221; : { &#8220;Ref&#8221; : &#8220;WebServerPort&#8221; }},<\/p>\n<p>&#8220;SecurityGroups&#8221; : [ { &#8220;Ref&#8221; : &#8220;InstanceSecurityGroup&#8221; } ],<\/p>\n<p>&#8220;InstanceType&#8221; : { &#8220;Ref&#8221; : &#8220;InstanceType&#8221; }<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;WebServerScaleUpPolicy&#8221; : {<\/p>\n<p>&#8220;Type&#8221; : &#8220;AWS::AutoScaling::ScalingPolicy&#8221;,<\/p>\n<p>&#8220;Properties&#8221; : {<\/p>\n<p>&#8220;AdjustmentType&#8221; : &#8220;ChangeInCapacity&#8221;,<\/p>\n<p>&#8220;AutoScalingGroupName&#8221; : { &#8220;Ref&#8221; : &#8220;WebServerGroup&#8221; },<\/p>\n<p>&#8220;Cooldown&#8221; : &#8220;60&#8221;,<\/p>\n<p>&#8220;ScalingAdjustment&#8221; : &#8220;1&#8221;<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;WebServerScaleDownPolicy&#8221; : {<\/p>\n<p>&#8220;Type&#8221; : &#8220;AWS::AutoScaling::ScalingPolicy&#8221;,<\/p>\n<p>&#8220;Properties&#8221; : {<\/p>\n<p>&#8220;AdjustmentType&#8221; : &#8220;ChangeInCapacity&#8221;,<\/p>\n<p>&#8220;AutoScalingGroupName&#8221; : { &#8220;Ref&#8221; : &#8220;WebServerGroup&#8221; },<\/p>\n<p>&#8220;Cooldown&#8221; : &#8220;60&#8221;,<\/p>\n<p>API Version 2010-05-15<\/p>\n<p>&#8220;ScalingAdjustment&#8221; : &#8220;-1&#8221;<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;CPUAlarmHigh&#8221;: {<\/p>\n<p>&#8220;Type&#8221;: &#8220;AWS::CloudWatch::Alarm&#8221;,<\/p>\n<p>&#8220;Properties&#8221;: {<\/p>\n<p>&#8220;AlarmDescription&#8221;: &#8220;Scale-up if CPU &gt; 90% for 10 minutes&#8221;,<\/p>\n<p>&#8220;MetricName&#8221;: &#8220;CPUUtilization&#8221;,<\/p>\n<p>&#8220;Namespace&#8221;: &#8220;AWS\/EC2&#8221;,<\/p>\n<p>&#8220;Statistic&#8221;: &#8220;Average&#8221;,<\/p>\n<p>&#8220;Period&#8221;: &#8220;300&#8221;,<\/p>\n<p>&#8220;EvaluationPeriods&#8221;: &#8220;2&#8221;,<\/p>\n<p>&#8220;Threshold&#8221;: &#8220;90&#8221;,<\/p>\n<p>&#8220;AlarmActions&#8221;: [ { &#8220;Ref&#8221;: &#8220;WebServerScaleUpPolicy&#8221; } ],<\/p>\n<p>&#8220;Dimensions&#8221;: [<\/p>\n<p>{<\/p>\n<p>&#8220;Name&#8221;: &#8220;AutoScalingGroupName&#8221;,<\/p>\n<p>&#8220;Value&#8221;: { &#8220;Ref&#8221;: &#8220;WebServerGroup&#8221; }<\/p>\n<p>}<\/p>\n<p>],<\/p>\n<p>&#8220;ComparisonOperator&#8221;: &#8220;GreaterThanThreshold&#8221;<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;CPUAlarmLow&#8221;: {<\/p>\n<p>&#8220;Type&#8221;: &#8220;AWS::CloudWatch::Alarm&#8221;,<\/p>\n<p>&#8220;Properties&#8221;: {<\/p>\n<p>&#8220;AlarmDescription&#8221;: &#8220;Scale-down if CPU &lt; 70% for 10 minutes&#8221;,<\/p>\n<p>&#8220;MetricName&#8221;: &#8220;CPUUtilization&#8221;,<\/p>\n<p>&#8220;Namespace&#8221;: &#8220;AWS\/EC2&#8221;,<\/p>\n<p>&#8220;Statistic&#8221;: &#8220;Average&#8221;,<\/p>\n<p>&#8220;Period&#8221;: &#8220;300&#8221;,<\/p>\n<p>&#8220;EvaluationPeriods&#8221;: &#8220;2&#8221;,<\/p>\n<p>&#8220;Threshold&#8221;: &#8220;70&#8221;,<\/p>\n<p>&#8220;AlarmActions&#8221;: [ { &#8220;Ref&#8221;: &#8220;WebServerScaleDownPolicy&#8221; } ],<\/p>\n<p>&#8220;Dimensions&#8221;: [<\/p>\n<p>{<\/p>\n<p>&#8220;Name&#8221;: &#8220;AutoScalingGroupName&#8221;,<\/p>\n<p>&#8220;Value&#8221;: { &#8220;Ref&#8221;: &#8220;WebServerGroup&#8221; }<\/p>\n<p>}<\/p>\n<p>],<\/p>\n<p>&#8220;ComparisonOperator&#8221;: &#8220;LessThanThreshold&#8221;<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;ElasticLoadBalancer&#8221; : {<\/p>\n<p>&#8220;Type&#8221; : &#8220;AWS::ElasticLoadBalancing::LoadBalancer&#8221;,<\/p>\n<p>&#8220;Properties&#8221; : {<\/p>\n<p>&#8220;AvailabilityZones&#8221; : { &#8220;Fn::GetAZs&#8221; : &#8220;&#8221; },<\/p>\n<p>&#8220;Listeners&#8221; : [ {<\/p>\n<p>&#8220;LoadBalancerPort&#8221; : &#8220;80&#8221;,<\/p>\n<p>&#8220;InstancePort&#8221; : { &#8220;Ref&#8221; : &#8220;WebServerPort&#8221; },<\/p>\n<p>&#8220;Protocol&#8221; : &#8220;HTTP&#8221;<\/p>\n<p>} ],<\/p>\n<p>&#8220;HealthCheck&#8221; : {<\/p>\n<p>&#8220;Target&#8221; : { &#8220;Fn::Join&#8221; : [ &#8220;&#8221;, [&#8220;HTTP:&#8221;, { &#8220;Ref&#8221; : &#8220;WebServerPort&#8221; },<\/p>\n<p>&#8220;\/&#8221;]]},<\/p>\n<p>&#8220;HealthyThreshold&#8221; : &#8220;3&#8221;,<\/p>\n<p>API Version 2010-05-15<\/p>\n<p>46<\/p>\n<p>AWS CloudFormation User Guide<\/p>\n<p>Auto Scaling Group with LoadBalancer, Auto Scaling<\/p>\n<p>Policies, and CloudWatch Alarms<\/p>\n<p>&#8220;UnhealthyThreshold&#8221; : &#8220;5&#8221;,<\/p>\n<p>&#8220;Interval&#8221; : &#8220;30&#8221;,<\/p>\n<p>&#8220;Timeout&#8221; : &#8220;5&#8221;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>},<\/p>\n<p>&#8220;InstanceSecurityGroup<\/p>\n<p>In the coming blogs let us look at the other cool features of AWS<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Any real time application is going to require more than 1 resource for its operation &#8211; for example a web&#8230;<\/p>\n","protected":false},"author":47,"featured_media":39401,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4659],"tags":[748,749,750],"practice_industry":[4516],"coauthors":[747],"class_list":["post-821","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-adoption","tag-cloud-2","tag-saas","tag-saascloud","practice_industry-cloud"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/posts\/821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/users\/47"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/comments?post=821"}],"version-history":[{"count":1,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/posts\/821\/revisions"}],"predecessor-version":[{"id":39508,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/posts\/821\/revisions\/39508"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/media\/39401"}],"wp:attachment":[{"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/media?parent=821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/categories?post=821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/tags?post=821"},{"taxonomy":"practice_industry","embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/practice_industry?post=821"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.aspiresys.com\/blog\/wp-json\/wp\/v2\/coauthors?post=821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}