Docker on Amazon Web Services
上QQ阅读APP看书,第一时间看更新

Updating a CloudFormation Stack

After you have created a CloudFormation stack, you may want to make changes to the stack, such as adding additional resources, or changing the configuration of existing resources. CloudFormation defines three key life cycle events related to stacks CREATE, UPDATE, and DELETE and these can apply to individual resources within the stack, or to the stack as a whole.

To update a stack, you simply make any required changes to your CloudFormation template and submit the modified template—the CloudFormation service will calculate the required changes for each resource, which may result in the creation of new resources, updating or replacement of existing resources, or deletion of existing resources. CloudFormation will also make any new changes first, and only if these changes are successful will it then clean up any resources that should be removed. This provides a higher chance of recovery in the event that a CloudFormation stack update fails, in which case CloudFormation will attempt to roll back the changes to restore the stack to its original state.

To test updating your CloudFormation stack, let's make a small change to the stack.yml template:

AWSTemplateFormatVersion: "2010-09-09"

Description: Cloud9 Management Station

Parameters:
EC2InstanceType:
Type: String
Description: EC2 instance type
Default: t2.micro
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Target subnet for instance

Resources:
ManagementStation:
Type: AWS::Cloud9::EnvironmentEC2
Properties:
Name: !Sub ${AWS::StackName}-station
Description:
Fn::Sub: ${AWS::StackName} Station
AutomaticStopTimeMinutes: 20
InstanceType: !Ref EC2InstanceType
SubnetId:
Ref: SubnetId

To apply this change, instead of using the AWS console, we will use the AWS CLI, which supports deploying your CloudFormation templates via the aws cloudformation deploy command. We will be using this command extensively throughout the remainder of this book, so now is a good time to introduce the command:

> export AWS_PROFILE=docker-in-aws
> aws cloudformation deploy --stack-name cloud9-management --template-file stack.yml \
--parameter-overrides SubnetId=subnet-a5d3ecee
Enter MFA code for arn:aws:iam::385605022855:mfa/justin.menga: ******

Waiting for changeset to be created..
Waiting for stack create/update to complete

Failed to create/update the stack. Run the following command
to fetch the list of events leading up to the failure
aws cloudformation describe-stack-events --stack-name cloud9-management

In the preceding code, we first ensure that the correct profile is configured, and then run the aws cloudformation deploy command, specifying the stack name using the --stack-name flag and template file with the --template-file flag. The --parameter-overrides flag allows you to supply input parameter values in the format <parameter>=<value> note that in an update scenario like this one, if you don't specify any parameter overrides, the previous parameter values provided (when you created the stack, in this case) will be used.

Notice that the update actually fails, and if you view the stack events via the CloudFormation console, you can find out why the stack update failed:

CloudFormation stack update failure

In the preceding screenshot, you can see that the stack update failed because the change required CloudFormation to create and replace the existing resource (in this case, the Cloud9 environment) with a new resource. As CloudFormation always attempts to create new resources before destroying any old resources that have been replaced, because the resource is configured with a name, CloudFormation cannot create a new resource with the same name, causing a failure. This highlights one of the important gotchas of CloudFormation—be very careful when defining your resources with static names—if CloudFormation ever needs to replace the resource in an update scenario like this one, the update will fail as generally, resource names must be unique.

For guidance on when CloudFormation will choose to replace a resource if you are updating the resource, refer to the resource properties defined for each resource type in the AWS Resource Types Reference document.

You can see that CloudFormation automatically rolls back the change after the failure, reversing any changes that were made leading up to the failure. The status of the stack eventually changes to UPDATE_ROLLBACK_COMPLETE, indicating that a failure and rollback took place.

One fix for resolving the stack failure would be to remove the Name property on the ManagementStation resource in your stack in this instance, CloudFormation will ensure it generates a unique name (typically based from the CloudFormation stack name with some random alphanumeric characters appended), meaning any time you update the resource so that it requires a replacement, CloudFormation will simply generate a new unique name and avoid the failure scenario we encountered.