Walkthrough: Use AWS CloudFormation Designer to modify a stack's template - AWS CloudFormation

Walkthrough: Use AWS CloudFormation Designer to modify a stack's template

You can use AWS CloudFormation Designer to modify a stack's template, and then submit it to AWS CloudFormation to update the stack. Typically, when you modify a stack, you need to get a copy of its template, modify the template in a text editor, and then use CloudFormation to update the stack. With AWS CloudFormation Designer, you can quickly get a copy of any running stack's template, modify it, and then update the stack without ever leaving the console.

In this walkthrough, we'll start with a basic web server stack, and then modify it so that the web server is scalable and durable.

In this walkthrough, we will complete the following steps:

  1. Get a stack's template.

    We'll get a copy of a running stack's template; the same basic web server stack in the following walkthrough: Walkthrough: Use AWS CloudFormation Designer to create a basic web server.

  2. Modify the template.

    We'll use AWS CloudFormation Designer to modify the stack's template so that your website is scalable and durable by replacing the EC2 instance with an Auto Scaling group and an Elastic Load Balancing load balancer.

  3. Update the stack.

    After saving the modifications, we'll update the basic web server stack with the modified template.

    Note

    CloudFormation is a free service; however, you are charged for the AWS resources you include in your stacks at the current rate for each. For more information about AWS pricing, see the detail page for each product on http://aws.amazon.com.

  4. Delete the stack.

    We'll delete the stack to clean up all of the resources.

Prerequisites

This walkthrough assumes that you have a working knowledge of Amazon Virtual Private Cloud (Amazon VPC), Auto Scaling, Elastic Load Balancing, and CloudFormation. For context, each procedure provides some basic information about each resource.

Additionally, the walkthrough assumes that you completed the following walkthrough: Walkthrough: Use AWS CloudFormation Designer to create a basic web server. From that walkthrough, you should have a running stack named BasicWebServerStack.

Step 1: Get a stack template

In this step, we'll use AWS CloudFormation Designer to get and open a copy of a running stack's template.

To get a copy of a running stack's template
  1. Open the CloudFormation console at https://console.aws.amazon.com/cloudformation/.

  2. From the list of stacks, select the BasicWebServerStack.

  3. Choose Actions, and then View/Edit template in Designer.

CloudFormation gets a copy of the BasicWebServerStack stack's template and displays it in AWS CloudFormation Designer, where you can view the template resources and their relationships. In the following step, we'll use AWS CloudFormation Designer to modify the template.

Step 2: Modify a template

We'll modify the basic web server template by using AWS CloudFormation Designer's drag-and-drop interface and integrated JSON and YAML editor to replace the single Amazon EC2 instance with an Auto Scaling group and load balancer to make the web site scalable. If traffic to the web site suddenly increases, use Auto Scaling to quickly increase the number of web servers. The load balancer will equally distributes the traffic among the instances.

To modify a stack template
  1. Remove the WebServerInstance resource.

    1. Right-click the WebServerInstance resource.

    2. From the resource menu, choose Delete ( ).

    3. Choose OK to confirm.

  2. From the Resource types pane, add the following resources into the PublicSubnet resource: AutoScalingGroup, LaunchConfiguration, and LoadBalancer. Before adding resources, you might need to expand the subnet to include all the resources.

    The resources are organized by resource categories. The Auto Scaling group and launch configuration are in the AutoScaling category, and the load balancer is in the ElasticLoadBalancing category.

    Note

    These resources don't follow the container model, so AWS CloudFormation Designer doesn't automatically associate them with the subnet. We'll create connections later on in this step.

  3. From the Resource types pane in the EC2 category, add the SecurityGroup resource anywhere in the VPC except in the subnet.

    This security group will control the inbound and outbound traffic of the load balancer.

  4. Rename the resources to make them easier to identify:

    • Rename AutoScalingGroup to WebServerFleet

    • Rename LaunchConfiguration to WebServerLaunchConfig

    • Rename LoadBalancer to PublicElasticLoadBalancer

    • Rename SecurityGroup to PublicLoadBalancerSecurityGroup

  5. Create associations for the resources that you added.

    1. Associate the load balancer and Auto Scaling group resources with the public subnet:

      • From the PublicElasticLoadBalancer resource, drag the AWS::EC2::Subnet (Property: Subnets) connection to the PublicSubnet resource.

      • From the WebServerFleet resource, drag the AWS::EC2::Subnet (Property: VPCZoneIdentifier) connection to the PublicSubnet resource.

    2. Associate the load balancer with its security group:

      • From the PublicElasticLoadBalancer resource, drag the AWS::EC2::SecurityGroup (Property: SecurityGroups) connection to the PublicLoadBalancerSecurityGroup resource.

    3. Associate the Auto Scaling group with the load balancer and launch configuration:

      • From the WebServerFleet resource, drag the AWS::ElasticLoadBalancing::LoadBalancer (Property: LoadBalancerNames) connection to the PublicElasticLoadBalancer resource.

      • From the WebServerFleet resource, drag the AWS::ElasticLoadBalancing::LaunchConfiguration (Property: LaunchConfigurationName) connection to the WebServerLaunchConfig resource.

    4. Associate the launch configuration with the security group:

      • From the WebServerLaunchConfig resource, drag the AWS::EC2::SecurityGroup (Property: SecurityGroups) connection to the WebServerSecurityGroup resource.

    5. Define a dependency for the Auto Scaling group to the public route:

      • From the WebServerFleet resource, drag the DependsOn connection to the PublicRoute resource.

      This dependency means that CloudFormation won't create the WebServerFleet resource until the public route is complete. Otherwise, if the public route isn't available when the web server instances are starting up, they won't be able to send signals (using the cfn-signal helper script) to notify CloudFormation when their configurations and application deployments are complete.

  6. Specify the properties for the resources that you added.

    1. On the AWS CloudFormation Designer canvas, choose the PublicElasticLoadBalancer resource.

    2. In the integrated editor pane, choose the Properties tab, and then copy the following snippet and paste it between the Properties braces ({}).

      AWS CloudFormation Designer automatically added the security group and subnet association, so you need to add only the Listeners and HealthCheck properties. The Listeners property specifies where and what type of traffic to listen for, and the HealthCheck property describes the settings for determining the health status of the load balancer.

      JSON

      "Listeners": [ { "LoadBalancerPort": "80", "InstancePort": "80", "Protocol": "HTTP" } ], "HealthCheck": { "Target": "HTTP:80/", "HealthyThreshold": "3", "UnhealthyThreshold": "5", "Interval": "90", "Timeout": "60" }, "SecurityGroups": [ { "Ref": "PublicLoadBalancerSecurityGroup" } ], "Subnets": [ { "Ref": "PublicSubnet" } ]

      YAML

      Listeners: - LoadBalancerPort: '80' InstancePort: '80' Protocol: HTTP HealthCheck: Target: 'HTTP:80/' HealthyThreshold: '3' UnhealthyThreshold: '5' Interval: '90' Timeout: '60' SecurityGroups: - !Ref PublicLoadBalancerSecurityGroup Subnets: - !Ref PublicSubnet
    3. Repeat this process for the following resources:

      WebServerFleet

      Add the MaxSize, MinSize, and DesiredCapacity properties. These properties specify the maximum and minimum number of instances that you can launch in the Auto Scaling group and the initial number of instances to start with. The desired capacity value refers to a new parameter, which we'll add later in this procedure.

      JSON

      "MinSize": "1", "MaxSize": "10", "DesiredCapacity": { "Ref": "WebServerCount" }, "VPCZoneIdentifier": [ { "Ref": "PublicSubnet" } ], "LaunchConfigurationName": { "Ref": "WebServerLaunchConfig" }, "LoadBalancerNames": [ { "Ref": "PublicElasticLoadBalancer" } ]

      YAML

      MinSize: '1' MaxSize: '10' DesiredCapacity: !Ref WebServerCount VPCZoneIdentifier: - !Ref PublicSubnet LaunchConfigurationName: !Ref WebServerLaunchConfig LoadBalancerNames: - !Ref PublicElasticLoadBalancer
      PublicLoadBalancerSecurityGroup

      Add the following inbound and outbound rules that determine the traffic that can reach and leave the load balancer. The rules allows all HTTP traffic to reach and leave the load balancer.

      JSON

      "GroupDescription": "Public Elastic Load Balancing security group with HTTP access on port 80 from the Internet", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" } ], "SecurityGroupEgress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" } ], "VpcId": { "Ref": "VPC" }

      YAML

      GroupDescription: >- Public Elastic Load Balancing security group with HTTP access on port 80 from the Internet SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 VpcId: !Ref VPC
      WebServerSecurityGroup

      Modify the HTTP inbound rule to allow only traffic from the load balancer.

      JSON

      "GroupDescription": "Allow access from load balancer and SSH traffic", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "SourceSecurityGroupId": { "Ref": "PublicLoadBalancerSecurityGroup" } }, { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": { "Ref": "SSHLocation" } } ], "VpcId": { "Ref": "VPC" }

      YAML

      VpcId: !Ref VPC GroupDescription: Allow access from load balancer and SSH traffic SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !Ref PublicLoadBalancerSecurityGroup - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation
      WebServerLaunchConfig

      The launch configuration has a number of different properties that you need to specify, so we'll highlight just a few of them. The InstanceType and ImageId properties use the parameter and mapping values that were already specified in the template. You specify the instance type as a parameter value when you create a stack. The ImageId value is a mapping that's based on your stack's region and the instance type that you specified.

      In the UserData property, we specify configurations scripts that run after the instance is up and running. The configuration information is defined in the instance's metadata, which we'll add in the next step.

      JSON

      "InstanceType": { "Ref": "InstanceType" }, "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "InstanceType" }, "Arch" ] } ] }, "KeyName": { "Ref": "KeyName" }, "AssociatePublicIpAddress": "true", "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash -xe\n", "yum install -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref": "AWS::StackName" }, " --resource WebServerLaunchConfig ", " --configsets All ", " --region ", { "Ref": "AWS::Region" }, "\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref": "AWS::StackName" }, " --resource WebServerFleet ", " --region ", { "Ref": "AWS::Region" }, "\n" ] ] } }, "SecurityGroups": [ { "Ref": "WebServerSecurityGroup" } ]

      YAML

      InstanceType: !Ref InstanceType ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch KeyName: !Ref KeyName AssociatePublicIpAddress: 'true' UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum install -y aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerLaunchConfig ' - ' --configsets All ' - ' --region ' - !Ref 'AWS::Region' - |+ - | # Signal the status from cfn-init - '/opt/aws/bin/cfn-signal -e $? ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerFleet ' - ' --region ' - !Ref 'AWS::Region' - |+ SecurityGroups: - !Ref WebServerSecurityGroup
  7. Add the launch configuration metadata to the WebServerLaunchConfig resource, which instructs the cfn-init helper script to start the web server and create a basic web page.

    1. Choose the WebServerLaunchConfig resource, and then choose the Metadata tab in the integrated editor.

    2. If you are authoring your template in JSON: Within the Metadata braces ({}), after the AWS::CloudFormation::Designer closing brace, add a comma (,).

    3. Add the following snippet, which instructs the cfn-init helper script to start the web server and create a basic web page, after the AWS::CloudFormation::Designer property.

      JSON

      "AWS::CloudFormation::Init" : { "configSets" : { "All" : [ "ConfigureSampleApp" ] }, "ConfigureSampleApp" : { "packages" : { "yum" : { "httpd" : [] } }, "files" : { "/var/www/html/index.html" : { "content" : { "Fn::Join" : ["\n", [ "<h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1>" ]]}, "mode" : "000644", "owner" : "root", "group" : "root" } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" } } } } }

      YAML

      'AWS::CloudFormation::Init': configSets: All: - ConfigureSampleApp ConfigureSampleApp: packages: yum: httpd: [] files: /var/www/html/index.html: content: !Join - |+ - - >- <h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1> mode: '000644' owner: root group: root services: sysvinit: httpd: enabled: 'true' ensureRunning: 'true'
  8. Add the WebServerCount parameter. This parameter specifies how many instances to create when CloudFormation creates the Auto Scaling group.

    1. Select on an open area on the AWS CloudFormation Designer canvas.

    2. In the integrated editor pane, choose the Parameters tab.

    3. Add the following parameter in the integrated editor. If you're authoring the template in JSON, add a comma as needed.

      JSON

      "WebServerCount": { "Description": "Number of Amazon EC2 instances to launch for the WebServer server", "Type": "Number", "Default": "1" }

      YAML

      WebServerCount: Description: Number of Amazon EC2 instances to launch for the WebServer server Type: Number Default: '1'
  9. Modify the template output to show the DNS name of the load balancer.

    1. In the integrated editor pane, choose the Outputs tab.

    2. Modify the JSON to use the load balancer DNS name, as shown in the following snippet.

      JSON

      { "Outputs": { "URL": { "Value": { "Fn::GetAtt": [ "PublicElasticLoadBalancer", "DNSName" ] }, "Description": "Newly created application URL" } } }

      If you're authoring your template in YAML, use the following snippet.

      Outputs: URL: Value: !GetAtt - PublicElasticLoadBalancer - DNSName Description: Newly created application URL
  10. On the AWS CloudFormation Designer toolbar, choose Validate template ( ) to check for syntax errors in your template.

    View and fix errors in the Messages pane, and then validate the template again. If you don't see errors, your template is syntactically valid.

  11. From the AWS CloudFormation Designer toolbar, save the template locally by choosing File ( ) and then Save.

You now have a modified CloudFormation template that you can use to update the basic web server stack. In the next step, we'll use this template to update the basic web server stack.

Step 3: Update the stack

To implement your template changes, we need to update the basic web server stack. You can launch the CloudFormation Update Stack Wizard directly from AWS CloudFormation Designer.

To update the stack
  1. On the AWS CloudFormation Designer toolbar, choose Create Stack ( ).

    AWS CloudFormation Designer saves the opened template in an S3 bucket and then launches the CloudFormation Update Stack Wizard. Because we modified the BasicWebServerStack stack's template, CloudFormation launches the Update Stack Wizard for that stack.

  2. CloudFormation automatically populates the template URL; choose Next.

  3. In the Stack section, in the Name field, verify that the stack name is BasicWebServerStack.

  4. In the Parameters section, use the existing values; choose Next.

  5. For this walkthrough, you don't need to add tags or specify advanced settings, so choose Next.

  6. Ensure that the stack name is correct, and then choose Update.

It can take several minutes for CloudFormation to update your stack. To monitor progress, view the stack events. For more information, see Viewing AWS CloudFormation stack data and resources on the AWS Management Console. After the stack is updated, view the stack outputs and go to the website URL to verify that the website is running. For more information, see Viewing AWS CloudFormation stack data and resources on the AWS Management Console. You successfully updated a template and a stack using AWS CloudFormation Designer.

To ensure that you aren't charged for unwanted services, you can delete this stack.

Step 4: Clean up resources

To make sure you aren't charged for unwanted services, delete your stack and it's resources.

To delete the stack
  1. From the CloudFormation console, choose the BasicWebServerStack stack.

  2. Choose Delete Stack.

  3. In the confirmation message, choose Yes, Delete.

It can take several minutes for CloudFormation to delete your stack. To monitor progress, view the stack events. After the stack is deleted, all the resources that you created are deleted. Now that you understand how to use AWS CloudFormation Designer, you can use it to build and modify your own templates.