示例更改集 - Amazon CloudFormation
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

示例更改集

此部分提供 CloudFormation 将为通用堆栈更改创建的更改集示例。它们显示如何直接编辑模板;修改单个输入参数;计划资源重新创建 (替换),这可防止您丢失未备份的数据或者中断正在堆栈中运行的应用程序;以及添加和删除资源。为了说明更改集的工作原理,我们将演练提交的更改,并说明生成的更改集。由于每个示例在之前的示例基础上构建并且假定您已了解之前的示例,我们建议您按顺序阅读。有关更改集中各个字段的说明,请参阅《Amazon CloudFormation API 参考》中的更改数据类型。

您可以使用控制台、Amazon CLI 或 CloudFormation DescribeChangeSet API 操作来查看更改集详细信息。

我们使用以下示例模板从堆栈生成以下各个更改集:

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "A sample EC2 instance template for testing change sets.", "Parameters" : { "Purpose" : { "Type" : "String", "Default" : "testing", "AllowedValues" : ["testing", "production"], "Description" : "The purpose of this instance." }, "KeyPairName" : { "Type": "AWS::EC2::KeyPair::KeyName", "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance" }, "InstanceType" : { "Type" : "String", "Default" : "t2.micro", "AllowedValues" : ["t2.micro", "t2.small", "t2.medium"], "Description" : "The EC2 instance type." } }, "Resources" : { "MyEC2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "KeyName" : { "Ref" : "KeyPairName" }, "InstanceType" : { "Ref" : "InstanceType" }, "ImageId" : "ami-8fcee4e5", "Tags" : [ { "Key" : "Purpose", "Value" : { "Ref" : "Purpose" } } ] } } } }

直接编辑模板

当您在堆栈模板中直接修改资源以生成更改集时,CloudFormation 将更改分为直接修改类,这与由更新后的参数值启动的更改相对。以下更改集添加新标签到 i-1abc23d4 实例,是直接修改的示例。所有其他输入值,例如参数值和功能均不变,因此我们将侧重于 Changes 结构。

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/1a2345b6-0000-00a0-a123-00abc0abc000", "Status": "CREATE_COMPLETE", "ChangeSetName": "SampleChangeSet-direct", "Parameters": [ { "ParameterValue": "testing", "ParameterKey": "Purpose" }, { "ParameterValue": "MyKeyName", "ParameterKey": "KeyPairName" }, { "ParameterValue": "t2.micro", "ParameterKey": "InstanceType" } ], "Changes": [ { "ResourceChange": { "ResourceType": "AWS::EC2::Instance", "PhysicalResourceId": "i-1abc23d4", "Details": [ { "ChangeSource": "DirectModification", "Evaluation": "Static", "Target": { "Attribute": "Tags", "RequiresRecreation": "Never" } } ], "Action": "Modify", "Scope": [ "Tags" ], "LogicalResourceId": "MyEC2Instance", "Replacement": "False" }, "Type": "Resource" } ], "CreationTime": "2020-11-18T23:35:25.813Z", "Capabilities": [], "StackName": "SampleStack", "NotificationARNs": [], "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet-direct/1a2345b6-0000-00a0-a123-00abc0abc000" }

Changes 结构中,只有一个 ResourceChange 结构。此结构描述一些信息,诸如 CloudFormation 将更改的资源类型、CloudFormation 将采取的操作、资源的 ID、更改的范围,以及更改是否需要替换(此时 CloudFormation 将创建新资源,然后删除旧资源)。在示例中,更改集指示 CloudFormation 将修改 i-1abc23d4 EC2 实例的 Tags 属性,无需替换实例。

Details 结构中,CloudFormation 将此更改标记为直接修改,永远无需重新创建实例(替换)。您可以充满信心地执行此更改,知道 CloudFormation 不会替换实例。

CloudFormation 将此更改显示为 Static 评估。静态评估意味着 CloudFormation 可以在执行更改集之前确定标签的值。在一些情况下,CloudFormation 只有在执行更改集之后才可以确定值。CloudFormation 将这些更改标记为 Dynamic 评估。例如,如果您引用有条件替换的更新后资源,CloudFormation 无法确定是否会更改对更新后资源的引用。

修改输入参数值

在您修改输入参数值时,CloudFormation 为使用更新后参数值的每个资源生成两个更改。在本示例中,我们希望突出显示这些更改的样子以及您应该关注哪些信息。以下示例通过仅更改 Purpose 输入参数的值生成。

Purpose 参数指定 EC2 实例的标签键值。在示例中,参数值从 testing 更改为 production。新值显示在 Parameters 结构中。

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/1a2345b6-0000-00a0-a123-00abc0abc000", "Status": "CREATE_COMPLETE", "ChangeSetName": "SampleChangeSet", "Parameters": [ { "ParameterValue": "production", "ParameterKey": "Purpose" }, { "ParameterValue": "MyKeyName", "ParameterKey": "KeyPairName" }, { "ParameterValue": "t2.micro", "ParameterKey": "InstanceType" } ], "Changes": [ { "ResourceChange": { "ResourceType": "AWS::EC2::Instance", "PhysicalResourceId": "i-1abc23d4", "Details": [ { "ChangeSource": "DirectModification", "Evaluation": "Dynamic", "Target": { "Attribute": "Tags", "RequiresRecreation": "Never" } }, { "CausingEntity": "Purpose", "ChangeSource": "ParameterReference", "Evaluation": "Static", "Target": { "Attribute": "Tags", "RequiresRecreation": "Never" } } ], "Action": "Modify", "Scope": [ "Tags" ], "LogicalResourceId": "MyEC2Instance", "Replacement": "False" }, "Type": "Resource" } ], "CreationTime": "2020-11-18T23:59:18.447Z", "Capabilities": [], "StackName": "SampleStack", "NotificationARNs": [], "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000" }

Changes 结构函数发挥作用的方式与在直接编辑模板示例中类似。只有一个 ResourceChange 结构;它描述了对 Tags EC2 实例的 i-1abc23d4 属性的更改。

但是,在 Details 结构中,更改集显示了 Tags 属性的两个更改,即使只更改了一个参数值。引用更改后参数值的资源 (使用 Ref 内部函数) 始终会导致两个更改:一个为 Dynamic 评估,另一个为 Static 评估。您可以通过查看以下字段查看这些更改类型:

  • 对于 Static 评估更改,请查看 ChangeSource 字段。在此示例中,ChangeSource 字段等于 ParameterReference,意味着此更改是更新参数引用值的结果。更改集必须包含类似的 Dynamic 评估更改。

  • 您可以通过比较所有更改的 Dynamic 结构来查找匹配的 Target 评估更改,这会包含同样的信息。在此示例中,所有更改的 Target 结构包含 AttributeRequireRecreation 字段的相同值。

对于这些类型的更改,重点在于静态评估,这向您提供了有关更改最详细的信息。在此示例中,静态评估显示更改是对参数引用值 (ParameterReference) 进行更改的结果。进行更改的确切参数由 CauseEntity 字段 (Purpose 参数) 指定。

确定“Replacement”字段中的值

ResourceChange 结构中的 Replacement 字段指示 CloudFormation 是否重新创建资源。计划重新创建资源 (替换) 可防止您丢失未备份的数据或者中断正在堆栈中运行的应用程序。

Replacement 字段中的值取决于更改是否需要替换,这由更改的 RequiresRecreation 结构中的 Target 字段指示。例如,如果 RequiresRecreation 字段为 Never,则 Replacement 字段为 False。但是,如果单个资源上有多个更改,并且每个更改有不同的 RequiresRecreation 字段值,CloudFormation 将使用最具侵入性的行为更新资源。换而言之,即使多个更改中只有一个需要替换,CloudFormation 必须替换资源,因此,将 Replacement 字段设置为 True

以下更改集通过更改每个参数 (PurposeInstanceTypeKeyPairName) 的值生成,这些参数均由 EC2 实例使用。通过这些更改,CloudFormation 需要替换实例,因为 Replacement 字段等于 True

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/1a2345b6-0000-00a0-a123-00abc0abc000", "Status": "CREATE_COMPLETE", "ChangeSetName": "SampleChangeSet-multiple", "Parameters": [ { "ParameterValue": "production", "ParameterKey": "Purpose" }, { "ParameterValue": "MyNewKeyName", "ParameterKey": "KeyPairName" }, { "ParameterValue": "t2.small", "ParameterKey": "InstanceType" } ], "Changes": [ { "ResourceChange": { "ResourceType": "AWS::EC2::Instance", "PhysicalResourceId": "i-7bef86f8", "Details": [ { "ChangeSource": "DirectModification", "Evaluation": "Dynamic", "Target": { "Attribute": "Properties", "Name": "KeyName", "RequiresRecreation": "Always" } }, { "ChangeSource": "DirectModification", "Evaluation": "Dynamic", "Target": { "Attribute": "Properties", "Name": "InstanceType", "RequiresRecreation": "Conditionally" } }, { "ChangeSource": "DirectModification", "Evaluation": "Dynamic", "Target": { "Attribute": "Tags", "RequiresRecreation": "Never" } }, { "CausingEntity": "KeyPairName", "ChangeSource": "ParameterReference", "Evaluation": "Static", "Target": { "Attribute": "Properties", "Name": "KeyName", "RequiresRecreation": "Always" } }, { "CausingEntity": "InstanceType", "ChangeSource": "ParameterReference", "Evaluation": "Static", "Target": { "Attribute": "Properties", "Name": "InstanceType", "RequiresRecreation": "Conditionally" } }, { "CausingEntity": "Purpose", "ChangeSource": "ParameterReference", "Evaluation": "Static", "Target": { "Attribute": "Tags", "RequiresRecreation": "Never" } } ], "Action": "Modify", "Scope": [ "Tags", "Properties" ], "LogicalResourceId": "MyEC2Instance", "Replacement": "True" }, "Type": "Resource" } ], "CreationTime": "2020-11-18T00:39:35.974Z", "Capabilities": [], "StackName": "SampleStack", "NotificationARNs": [], "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet-multiple/1a2345b6-0000-00a0-a123-00abc0abc000" }

通过查看各个更改 (Details 结构中的静态评估) 确定需要替换资源的更改。在此示例中,各个更改具有不同的 RequireRecreation 字段值,但对 KeyName 属性的更改是最具侵入性的更新行为,始终需要重新创建。CloudFormation 将替换实例,因为其键名称已更改。

如果键名称未更改,则对 InstanceType 属性的更改将为最具侵入性的更新行为 (Conditionally),因此 Replacement 字段将为 Conditionally。要查找 CloudFormation 替换实例的条件,请查看 InstanceType 属性的更新行为。

添加和删除资源

以下示例通过提交修改后的模板生成,此修改删除了 EC2 实例,并添加了自动扩缩组和启动配置。

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/1a2345b6-0000-00a0-a123-00abc0abc000", "Status": "CREATE_COMPLETE", "ChangeSetName": "SampleChangeSet-addremove", "Parameters": [ { "ParameterValue": "testing", "ParameterKey": "Purpose" }, { "ParameterValue": "MyKeyName", "ParameterKey": "KeyPairName" }, { "ParameterValue": "t2.micro", "ParameterKey": "InstanceType" } ], "Changes": [ { "ResourceChange": { "Action": "Add", "ResourceType": "AWS::AutoScaling::AutoScalingGroup", "Scope": [], "Details": [], "LogicalResourceId": "AutoScalingGroup" }, "Type": "Resource" }, { "ResourceChange": { "Action": "Add", "ResourceType": "AWS::AutoScaling::LaunchConfiguration", "Scope": [], "Details": [], "LogicalResourceId": "LaunchConfig" }, "Type": "Resource" }, { "ResourceChange": { "ResourceType": "AWS::EC2::Instance", "PhysicalResourceId": "i-1abc23d4", "Details": [], "Action": "Remove", "Scope": [], "LogicalResourceId": "MyEC2Instance" }, "Type": "Resource" } ], "CreationTime": "2020-11-18T01:44:08.444Z", "Capabilities": [], "StackName": "SampleStack", "NotificationARNs": [], "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet-addremove/1a2345b6-0000-00a0-a123-00abc0abc000" }

Changes 结构中,有三个 ResourceChange 结构,每个资源一个。对于每个资源,Action 字段指示 CloudFormation 添加还是删除资源。ScopeDetails 字段为空,因为它们仅适用于修改后的资源。

对于新资源,CloudFormation 无法确定一些字段的值,直至您执行更改集。例如,CloudFormation 不提供自动扩缩组的物理 ID 和启动配置,因为它们尚不存在。在您执行更改集时,CloudFormation 创建新资源。