Check CloudFormation Change Set to see the scope of impact when updating the stack
One of the AWS SOA topics is related to deployment, provisioning, and automation.
Change sets are available to safely update resources in CloudFormation.
Change sets allow you to preview how proposed changes to a stack might impact your running resources, for example, whether your changes will delete or replace any critical resources
Updating stacks using change sets
This page will confirm the operation of the CloudFormation change set.
Environment
Create a Lambda function using CloudFormation.
Create a change set after the function is created, check the impact of stack updates, and perform stack updates.
CloudFormation template files
The above configuration is built with CloudFormation.
We will build it with the following two template files.
soa-03-004.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: A sample EC2 instance template for testing change sets.
Parameters:
TemplateBucketName:
Type: String
Default: [bucket-name]
Prefix:
Type: String
Default: soa-03-004
Handler:
Type: String
Default: index.lambda_handler
Runtime:
Type: String
Default: python3.9
#Default: python3.8
Resources:
LambdaStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub "https://${TemplateBucketName}.s3.${AWS::Region}.amazonaws.com/${Prefix}/${Prefix}-lambda.yaml"
Parameters:
Handler: !Ref Handler
Prefix: !Ref Prefix
Runtime: !Ref Runtime
Code language: YAML (yaml)
soa-03-004-lambda.yaml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Handler:
Type: String
Prefix:
Type: String
Runtime:
Type: String
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
def lambda_handler(event, context):
print('hello, awstut !')
FunctionName: !Sub "${Prefix}-function"
#FunctionName: !Sub "${Prefix}-function-updated"
Handler: !Ref Handler
Role: !GetAtt FunctionRole.Arn
Runtime: !Ref Runtime
FunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
#S3Permission:
# Type: AWS::Lambda::Permission
# Properties:
# FunctionName: !Ref Function
# Action: lambda:InvokeFunction
# Principal: s3.amazonaws.com
# #SourceArn: !Ref SNSTopicArn
Code language: YAML (yaml)
The templates are also placed at the following URL
https://github.com/awstut-an-r/awstut-soa/tree/main/03/004
Explanation of key points of template files
No special configuration is required.
Lambda functions are described in inline format.
For more information on Lambda functions, please see the following page
Architecting
Use CloudFormation to build this environment and check its actual behavior.
Create CloudFormation stacks and check the resources in the stacks
Create CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following pages.
After reviewing the resources in each stack, information on the main resources created in this case is as follows
- Root Stack: soa-03-004
- Child Stack: soa-03-004-LambdaStack-1WUKC1VUIJ2Q1
- Lambda function: soa-03-004-function
Check each resource from the AWS Management Console.
Check the CloudFormation stacks.
You can see that two stacks have been created.
The former is the root stack and the other is the child stack.
Operation Check
You are ready to go.
Create a modified set of these stacks and see which work.
Create change sets and create resources
Change Set Creation
Define new resources as updates to the stack.
Make modifications to soa-03-004-lambda.yaml.
S3Permission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Function
Action: lambda:InvokeFunction
Principal: s3.amazonaws.com
Code language: YAML (yaml)
This is the part that was commented out.
Uncomment and define a resource-based policy for Lambda.
After placing the modified template file in place, create a change set.
In this case, we will place the template file in the S3 bucket.
The AWS CLI is used to create the change set.
$ aws cloudformation create-change-set \
--stack-name soa-03-004 \
--change-set-name SampleChangeSet \
--template-url https://[bucket-url]/soa-03-004.yaml \
--include-nested-stacks \
--capabilities CAPABILITY_IAM
Code language: Bash (bash)
For nested stacks, create a change set by specifying the root stack with the include-nested-stacks option enabled.
Check the change set created from the AWS Management Console.
The previous single operation created a change set on the root and child stacks, respectively.
Looking at the root stack, the action for the child stack is “Modify”.
Looking at the child stack, the S3Permission (Lambda’s resource-based policy) is “Add”.
By creating a change set, you can see the extent of the impact when the stack is updated.
By the way, if you want to check the change set using the AWS CLI, execute the following command
Check the change set for the root stack.
$ aws cloudformation list-change-sets --stack-name soa-03-004
{
"Summaries": [
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/soa-03-004/3e47fc40-8cf3-11ed-8f62-0651fa1f475b",
"StackName": "soa-03-004",
"ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:[account-id]:changeSet/SampleChangeSet/8e2bf911-7a1e-4951-9f39-fc94fe2ca7b6",
"ChangeSetName": "SampleChangeSet",
"ExecutionStatus": "AVAILABLE",
"Status": "CREATE_COMPLETE",
"CreationTime": "2023-01-05T12:30:44.145000+00:00",
"IncludeNestedStacks": true
}
]
}
$ aws cloudformation describe-change-set --change-set-name SampleChangeSet --stack-name soa-03-004
{
"Changes": [
{
"Type": "Resource",
"ResourceChange": {
"Action": "Modify",
"LogicalResourceId": "LambdaStack",
"PhysicalResourceId": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/soa-03-004-LambdaStack-1WUKC1VUIJ2Q1/40f541f0-8cf3-11ed-9f59-0e1182c6182d",
"ResourceType": "AWS::CloudFormation::Stack",
"Replacement": "False",
"Scope": [
"Properties"
],
"Details": [
{
"Target": {
"Attribute": "Properties",
"RequiresRecreation": "Never"
},
"Evaluation": "Dynamic",
"ChangeSource": "Automatic"
}
],
"ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:[account-id]:changeSet/SampleChangeSet-LambdaStack-3O37LKJ61939/9f630ba8-f400-4914-bf1d-68ce009445c6"
}
}
],
"ChangeSetName": "SampleChangeSet",
"ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:[account-id]:changeSet/SampleChangeSet/8e2bf911-7a1e-4951-9f39-fc94fe2ca7b6",
"StackId": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/soa-03-004/3e47fc40-8cf3-11ed-8f62-0651fa1f475b",
"StackName": "soa-03-004",
"Description": null,
"Parameters": [
{
"ParameterKey": "Runtime",
"ParameterValue": "python3.9"
},
{
"ParameterKey": "Handler",
"ParameterValue": "index.lambda_handler"
},
{
"ParameterKey": "Prefix",
"ParameterValue": "soa-03-004"
},
{
"ParameterKey": "TemplateBucketName",
"ParameterValue": "awstut-bucket"
}
],
"CreationTime": "2023-01-05T12:30:44.145000+00:00",
"ExecutionStatus": "AVAILABLE",
"Status": "CREATE_COMPLETE",
"StatusReason": null,
"NotificationARNs": [],
"RollbackConfiguration": {},
"Capabilities": [
"CAPABILITY_IAM"
],
"Tags": null,
"ParentChangeSetId": null,
"IncludeNestedStacks": true,
"RootChangeSetId": null
}
Code language: Bash (bash)
Stack update using change sets
You have created a change set and verified your changes.
The next step is to update the stack using the change set.
To update the stack, use the AWS CLI.
$ aws cloudformation execute-change-set \
--stack-name soa-03-004 \
--change-set-name SampleChangeSet
Code language: Bash (bash)
Check the update status in the AWS Management Console.
You can see that two stack change sets have been executed.
Looking at the resource generated from the child stack, an S3Permission is indeed created.
You can also use change sets in this way to update the stack.
Create change sets and updae resources
Check the change set when updating resources.
Modify the template file.
soa-03-004.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: A sample EC2 instance template for testing change sets.
Parameters:
TemplateBucketName:
Type: String
Default: [bucket-name]
Prefix:
Type: String
Default: soa-03-004
Handler:
Type: String
Default: index.lambda_handler
Runtime:
Type: String
#Default: python3.9
Default: python3.8
Resources:
LambdaStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub "https://${TemplateBucketName}.s3.${AWS::Region}.amazonaws.com/${Prefix}/${Prefix}-lambda.yaml"
Parameters:
Handler: !Ref Handler
Prefix: !Ref Prefix
Runtime: !Ref Runtime
Code language: YAML (yaml)
Change the default values of parameters.
This is related to the runtime environment of the Lambda function.
soa-03-004-lambda.yaml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Handler:
Type: String
Prefix:
Type: String
Runtime:
Type: String
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
def lambda_handler(event, context):
print('hello, awstut !')
#FunctionName: !Sub "${Prefix}-function"
FunctionName: !Sub "${Prefix}-function-updated"
Handler: !Ref Handler
Role: !GetAtt FunctionRole.Arn
Runtime: !Ref Runtime
FunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
S3Permission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Function
Action: lambda:InvokeFunction
Principal: s3.amazonaws.com
Code language: YAML (yaml)
The contents of the function name are to be changed.
Create a change set using the same procedure as before.
The following is the set of changes created
This is a set of changes to the root stack.
The value of the parameter Runtime has been changed, which is reflected here.
The parameter changes are reflected here as well.
It is noteworthy that the Replace two resources (Function, S3Permission) in the stack are marked “True”.
This means that resource replacement will occur when this update is executed.
The official AWS explanation of what it means for a resource to be replaced is as follows
AWS CloudFormation recreates the resource during an update, which also generates a new physical ID. AWS CloudFormation usually creates the replacement resource first, changes references from other dependent resources to point to the replacement resource, and then deletes the old resource.
Update behaviors of stack resources
This means that recreating the resource will cause the use of the resource to be suspended.
Now that we know that resource replacement occurs, let’s see how and why it is raw.
Details can be found on the JSON changes tab.
The data with a logicalResourceId value of “Function” is related to the Lambda function.
You can see the details of the changes in details.
It can be read that the values for Runtime and FunctionName have changed.
For Runtime, there are two sets of data, because the values in the Parameters section are referenced using the built-in function Fn::Ref.
Please see the following page for more information about this.
The key point is the value of requiresRecreation.
Performing a change with this value of “Always” will always result in resource replacement.
In other words, changing FunctionName will cause the resource to be replaced.
Similarly, in S3Permission, the value of requiresRecreation is “Always”.
Here, too, a change in the value of FunctionName causes the resource to be replaced.
This change was due to the aforementioned function renaming and was not directly attributable to the template file change.
By using change sets in this way, the scope of the impact of resource updates can be ascertained in advance.
Create change sets and delete resources
Check the change set when updating resources.
Modify the template file.
soa-03-004-lambda.yaml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Handler:
Type: String
Prefix:
Type: String
Runtime:
Type: String
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
def lambda_handler(event, context):
print('hello, awstut !')
FunctionName: !Sub "${Prefix}-function"
#FunctionName: !Sub "${Prefix}-function-updated"
Handler: !Ref Handler
Role: !GetAtt FunctionRole.Arn
Runtime: !Ref Runtime
FunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
#S3Permission:
# Type: AWS::Lambda::Permission
# Properties:
# FunctionName: !Ref Function
# Action: lambda:InvokeFunction
# Principal: s3.amazonaws.com
Code language: YAML (yaml)
Comment out S3Permission.
This means that this resource will be deleted.
Create a change set using the same procedure as before.
The following is the set of changes created
Looking at the parent stack, the child stack says “Modify”.
Looking at the child stack, the S3Permission is “Remove”.
By creating a change set in this manner, the scope of the impact of resource deletion can be ascertained.
Summary
CloudFormation change sets are now working.