CloudFormation 堆疊的變更集範例 - AWS CloudFormation

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

CloudFormation 堆疊的變更集範例

本節所提供的變更集範例能讓 CloudFormation 用來建立一般堆疊變更。這些範例將說明如何直接編輯範本、修改單一輸入參數、規劃資源重新建立 (替換) 作業,以免未備份的資料遺失,或是堆疊中執行的應用程式中斷;透過這些範例,您亦能掌握新增與移除資源的方法。為了示範變更集的運作方式,我們將逐步解說您所提交的變更,並探討隨後產生的變更集。本節的每個範例皆是以先前的範例為建立基礎,且會假設您已掌握之前的釋例,因此建議您按照順序詳讀。如需變更集各欄位的說明,請參閱《AWS CloudFormation API 參考》中的 Change (變更) 資料類型。

您可以使用主控台、 AWS 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/MyStack/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": "MyStack", "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 評估。Static 評估表示 CloudFormation 可以先判斷標籤值,再執行變更集。在某些情況下,唯有在執行變更集後,CloudFormation 才能判斷標籤值。而 CloudFormation 會將這類變更標記為 Dynamic 評估。假若更新後資源的參考資料將在滿足條件時進行替換作業,則 CloudFormation 便無法判斷更新後資源的參考資料是否會改變。

修改輸入參數值

當您修改輸入參數值時,CloudFormation 即會採用更新後的參數值,藉此為各個資源產生兩項變更。在本範例中,我們會詳細說明這些變更的效果,以及應注重的資訊。系統在產生本範例時,僅有變更 Purpose 輸入參數的值。

Purpose 參數會指定 EC2 執行個體的標籤金鑰值。本範例會將 testing 參數值變更為 production。而 Parameters 結構即會顯示新的值。

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/MyStack/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": "MyStack", "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 結構皆涵蓋相同的 Attribute 值和 RequireRecreation 欄位。

查看這類型的變更時,應該著重於 Static 評估,因為該評估所提供的變更資訊最為詳細。在本範例中,Static 評估顯示的變更屬於參數參考值 (ParameterReference) 的更改結果;CauseEntity 欄位 (Purpose 參數) 則會確切指示已變更的參數。

判斷 Replacement 欄位的值

ResourceChange 結構中的 Replacement 欄位會指示 CloudFormation 是否應重新建立資源。只需規劃資源的重新建立或替換作業,即可避免未備份的資料遺失,或是堆疊中執行的應用程式中斷。

Replacement 欄位中的值會取決於是否需要替換變更項目,這會視變更 RequiresRecreation 結構中的 Target 欄位指示而定。舉例來說,若 RequiresRecreation 欄位為 Never,則 Replacement 欄位的值將為 False。但若單一資源上有多項變更,且各變更在 RequiresRecreation 欄位中的值皆不相同,CloudFormation 即會透過最具侵入性的行為來更新資源。換而言之,即使多項變更中僅有其中一項需要替換,CloudFormation 仍必須取代整個資源;因此,請將 Replacement 欄位設為 True

系統會變更每個 PurposeInstanceTypeKeyPairName 參數的值,藉此產生下列變更集,而這些參數皆可供 EC2 執行個體使用。一旦執行這些變更,Replacement 欄位將等於 True,所以 CloudFormation 需要替換執行個體。

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/MyStack/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": "MyStack", "NotificationARNs": [], "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet-multiple/1a2345b6-0000-00a0-a123-00abc0abc000" }

您可以檢視各項變更 (意即為 Details 結構中的 Static 評估),藉此找出需替換資源的變更。在本範例中,儘管每項變更在 RequireRecreation 欄位中的值皆不相同,但一律要執行重新建立操作,因為系統在變更 KeyName 屬性時會採取最具侵入性的更新行為。由於金鑰名稱有所改變,CloudFormation 將替換執行個體。

若金鑰名稱保持不變,則系統變更 InstanceType 屬性時會採取最具侵入性的更新行為 (Conditionally);如此一來,Replacement 欄位的值將為 Conditionally。若要尋找 CloudFormation 替換執行個體的條件,請檢視 AWS::EC2::Instance 資源高達的 InstanceType 屬性的更新行為。

新增與移除資源

以下範例是透過提交修改過的範本來產生,該範本會移除 EC2 執行個體並新增 Amazon EC2 Auto Scaling 群組和啟動組態。

{ "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/MyStack/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": "MyStack", "NotificationARNs": [], "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet-addremove/1a2345b6-0000-00a0-a123-00abc0abc000" }

Changes 結構中有三種 ResourceChange 結構,每個資源各有一種結構。每個資源的 Action 欄位均會指示 CloudFormation 應新增或移除資源。ScopeDetails 欄位則沒有內容,因為這些欄位僅適用於修改後的資源。

使用新資源時,您必須執行變更集,否則 CloudFormation 將無法判斷部分欄位的值。例如,CloudFormation 不提供 Amazon EC2 Auto Scaling 群組的實體 IDs 和啟動組態,因為這些組態尚不存在。當您執行變更集時,CloudFormation 即會建立新資源。

檢視屬性層級變更

下列範例顯示 Amazon EC2 執行個體屬性的 Tag 屬性層級變更。標籤 ValueKey 將變更為 Test

"ChangeSetName": "SampleChangeSet", "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet/38d91d27-798d-4736-9bf1-fb7c46207807", "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleEc2Template/68edcdc0-f6b6-11ee-966c-126d572cdd11", "StackName": "SampleEc2Template", "Description": "A sample EC2 instance template for testing change sets.", "Parameters": [ { "ParameterKey": "KeyPairName", "ParameterValue": "BatchTest" }, { "ParameterKey": "Purpose", "ParameterValue": "testing" }, { "ParameterKey": "InstanceType", "ParameterValue": "t2.micro" } ], "CreationTime": "2024-04-09T21:29:10.759000+00:00", "ExecutionStatus": "AVAILABLE", "Status": "CREATE_COMPLETE", "StatusReason": null, "NotificationARNs": [], "RollbackConfiguration": { :...skipping... { "Changes": [ { "Type": "Resource", "ResourceChange": { "Action": "Modify", "LogicalResourceId": "MyEC2Instance", "PhysicalResourceId": "i-0cc7856a36315e62b", "ResourceType": "AWS::EC2::Instance", "Replacement": "False", "Scope": [ "Tags" ], "Details": [ { "Target": { "Attribute": "Tags", "RequiresRecreation": "Never", "Path": "/Properties/Tags/0/Value", "BeforeValue": "testing", "AfterValue": "Test", "AttributeChangeType": "Modify" }, "Evaluation": "Static", "ChangeSource": "DirectModification" }, { "Target": { "Attribute": "Tags", "RequiresRecreation": "Never", "Path": "/Properties/Tags/0/Key", "BeforeValue": "Purpose", "AfterValue": "Test", "AttributeChangeType": "Modify" }, "Evaluation": "Static", "ChangeSource": "DirectModification" } ], "BeforeContext": "{\"Properties\":{\"KeyName\":\"BatchTest\",\"ImageId\":\"ami-8fcee4e5\",\"InstanceType\":\"t2.micro\",\"Tags\":[{\"Value\":\"testing\",\"Key\":\"Purpose\"}]}}", "AfterContext": "{\"Properties\":{\"KeyName\":\"BatchTest\",\"ImageId\":\"ami-8fcee4e5\",\"InstanceType\":\"t2.micro\",\"Tags\":[{\"Value\":\"Test\",\"Key\":\"Test\"}]}}" } } ]

Details 結構會顯示執行變更集前 KeyValue 的值,以及執行變更集後其預期數值。