AWS Official Blog

The CloudFormation Circle of Life : Part 1

by Jeff Barr | on | in AWS CloudFormation |

Today we have a blog post from Chris Whitaker of the AWS CloudFormation team. Chris brings word of an important new CloudFormation feature, the ability to evolve a running stack by incrementally adding or removing resource definitions from the template.

– Jeff;


AWS CloudFormation makes it easier for you to create, update, and manage your AWS resources in a predictable way. Today, we are announcing a new feature for AWS CloudFormation that allows you to add or remove resources from your running stack, enabling your stack to evolve as its requirements change over time. With AWS CloudFormation, you can now manage the complete lifecycle the AWS resources powering your application.

Create the AWS Infrastructure for Your Application
CloudFormation templates define a set of AWS resources and their dependencies in a declarative way. You can think of a CloudFormation template as a blueprint that describes what you need to run your application. In this way, the CloudFormation service acts like an automated assembly line, building the resources and any dependencies they require consistently and predictably. CloudFormation allows you to define a broad range of resources, including most of the AWS services. Weve tried to make sure that you dont need to learn any concepts beyond those required by each AWS service. Each resource declared in the template has a logical name, a type, and a set of properties applicable to that resource type. Templates accept inputs (in the form of parameters) and produce outputs. Input parameters allow you to use a single template to build out different configurations of your resources, such as how many Amazon EC2 instances you need or to configure the password for an Amazon RDS Database instance. Templates can be region-aware so that you can use the same template to configure resources in the same way for different AWS regions.

Configure EC2 Instances and Deploy Your Application Code
In addition to AWS resources, templates can also define how an EC2 instance will be configured when it is launched. The template defines the software packages to be installed, additional files that should be created, OS users and groups needed, any services that need to be started and any additional commands that need to be run.

Change properties of Your Resources
Now that your application is up and running, it is likely that youll need to tweak some of the parameters for the resources. For example, you may want to change the threshold on one of you Amazon CloudWatch alarms or increase the maximum number of EC2 instances in an Auto Scaling group. CloudFormation allows you to update the properties of the resources in your templatesimply make the changes to your template and update the stack. CloudFormation will make updates in the most optimal way to reduce downtime. Some changes, such as modifying an alarm configuration, can be done in a non-intrusive way. CloudFormation gives you full controlyou can, for example, change the Amazon Machine Image (AMI) deployed to your EC2 instance. For these types of changes, your existing resource will be replaced with a new resource. To avoid downtime in this case, you can create new EC2 instances and then spin down your old ones. CloudFormation completes the update process by making any necessary changes to dependent resourcesif your Elastic IP address was referencing your old EC2 instance, then it will be automatically updated to point at your new instance.

Update the Software for Your Application
CloudFormation allows you to keep your software packages and application up to date in a fashion similar to how you update its resources. When you define the software to deploy, you can specify the versions of any needed packages. You can update your stack by simply changing the package version in the template or a set of dependent changes across multiple instances. CloudFormation also looks for changes to the contents of any files specified in the template or any additional users, groups, services or other artifacts that need to be laid down on the instance and applies them during an update. To leverage this functionality, you need to make sure you start up the cfn-hup process on your instance at launch time. The cfn-hup daemon runs in the background and coordinates with CloudFormation to apply changes to your instance.

Grow or Change the Resources Needed by Your Application
As your service grows and the software evolves, the set of AWS resources required by your application might change. CloudFormation now lets you change the resources in a stack over time. You may start off using a single instance to run your service and find you need to migrate to a load balanced, Auto Scaling group to service your requests. No worries, simply define the new resources in your template and let CloudFormation take care of the rest. Any new resources needed will be spun up and linked to the existing resources powering your applicationfor example, your new auto scaled instances may need to connect to your Amazon RDS database instance. Any resources you no longer need will be removed and decommissioned. As with updating properties of existing resources, CloudFormation will optimize the update to only impact those resources that need to be changed.

An Example
The AWS CloudFormation User Guide contains a walkthrough for creating a new stack and updating it covering the following scenarios:

  • Updating the software on the EC2 instance (software update).
  • Updating the EC2 instance type to scale vertically (e.g. to convert the stack from a t1.micro to a m1.small EC2 instance type).
  • Updating the Amazon Machine Image (AMI) on the EC2 instance in the stack.
  • Adding a Key Pair to an EC2 instance that does not have one, allowing you to login via SSH.
  • Updating the properties of existing resources such as IAM policies.

With the latest release of AWS CloudFormation, now you can change the set of resources that make up the stack. To demonstrate, well take the single instance application from the walkthrough and convert it to an auto scaled, load balanced application using AWS CloudFormation to update the stack.

Start by following the walkthrough in the AWS CloudFormation User Guide or create a stack using the following template: https://s3.amazonaws.com/cloudformation-templates-us-east-1/UpdateTutorialPart3.template.

This will create a simple, single instance PHP application using an Elastic IP address. To turn the application into a highly available, auto-scaled, load balanced application, we need to make the following changes to the template:

  1. Remove the Elastic IP address resource from the template:
        “Endpoint” : {
          “Type” : “AWS::EC2::EIP” ,
          “Properties” : {
            “InstanceId” : { “Ref” : “WebServerHost” }
          }
        } ,
  2. Add an Elastic Load Balancer resource:
        “ElasticLoadBalancer” : {
          “Type” : “AWS::ElasticLoadBalancing::LoadBalancer” ,
          “Properties” : {
            “AvailabilityZones” : { “Fn::GetAZs” : “” } ,
            “Listeners” : [ {
              “LoadBalancerPort” : “80” ,
              “InstancePort” : “80” ,
              “Protocol” : “HTTP”
            } ] ,
            “HealthCheck” : {
              “Target” : “HTTP:80/” ,
              “HealthyThreshold” : “3” ,
              “UnhealthyThreshold” : “5” ,
              “Interval” : “30” ,
              “Timeout” : “5”
            }
          }
        } ,
  3. Convert the EC2 instance in the template into an Auto Scaling Launch Configuration. The properties are identical, so we only need to change the type name.

    From:

        “WebServerHost” : {
          “Type” : “AWS::EC2::Instance” ,

    To:

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

    For clarity in the template, Ive also changed the name of the resource from WebServerHost to WebServerConfig, so youll need to update the resource name referenced by cfn-init and cfn-hup (just search for WebServerHost and replace it with WebServerConfig).

  4. Add an Auto Scaling Group resource:
        “WebServerGroup” : {
          “Type” : “AWS::AutoScaling::AutoScalingGroup” ,
          “Properties” : {
            “AvailabilityZones” : { “Fn::GetAZs” : “” } ,
            “LaunchConfigurationName” : { “Ref” : “WebServerConfig” } ,
            “MinSize” : “1” ,
            “MaxSize” : “3” ,
            “LoadBalancerNames” : [ { “Ref” : “ElasticLoadBalancer” } ]
          }
        } ,
  5. Update the Security Group definition to lock down the traffic to the instances from the load balancer:
        “WebServerSecurityGroup” : {
          “Type” : “AWS::EC2::SecurityGroup” ,
          “Properties” : {
            “GroupDescription” : “Enable SSH access and HTTP from the load balancer only” ,
            “SecurityGroupIngress” : [ {
              “IpProtocol” : “tcp” ,
              “FromPort” : “22” ,
              “ToPort” : “22” ,
              “CidrIp” : “0.0.0.0/0″
            } , {
              “IpProtocol” : “tcp” ,
              “FromPort” : “80” ,
              “ToPort” : “80” ,
              “SourceSecurityGroupOwnerId” : { “Fn::GetAtt” :      
                  [ “ElasticLoadBalancer” , “SourceSecurityGroup.OwnerAlias” ] } ,
              “SourceSecurityGroupName” : { “Fn::GetAtt” :  
                  [ “ElasticLoadBalancer” , “SourceSecurityGroup.GroupName” ] }
            } ]
          }
        } ,
  6. Update the Outputs to return the DNS Name of the Elastic Load Balancer as the location of the application:

    From:

        “WebsiteURL” : {
          “Value” : { “Fn::Join” : [ “” , [ “http://” , { “Ref” : “Endpoint” } ] ] } ,
          “Description” : “Application URL”
        }

    To:

        “WebsiteURL” : {
          “Value” :   { “Fn::Join” : [ “” , [ “http://” ,
              { “Fn::GetAtt” : [ “ElasticLoadBalancer” , “DNSName” ] } ] ] } ,
          “Description” : “Application URL”
        }

You can download or reference the complete template at: https://s3.amazonaws.com/cloudformation-templates-us-east-1/UpdateTutorialPart5.template .

If you use this template to update the stack, you will convert your simple, single instance application into a highly available, multi-AZ, auto-scaled and load balanced application. Only the resources that need to be updated will be altered, so, had there been any data stores for this application, the data would have remained intact. Now you can use CloudFormation to grow or enhance your stacks as your requirements change.

Summary
By providing a set of mechanisms for creating and updating resources as well as software components, CloudFormation enables the ongoing management of your applications infrastructure. CloudFormation templates can be version controlled alongside your application code and ensures that your change management processes take a holistic approach: you can be assured that your development, preproduction and production stacks are deployed and configured the same way and you can be sure that any change you test out prior to production is carried out in the same way as you propagate it across your stages.

– Chris

We are looking for highly motivated software developers and product managers who want to work on leading edge, highly scaled services such as AWS CloudFormation and AWS Elastic Beanstalk. If you are interested, send us your resume to aws-cloudformation-jobs at amazon.com or aws-elasticbeanstalk-jobs at amazon.com. Come and help us make history!