

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

# CloudFormation 堆疊的變更集範例
<a name="using-cfn-updating-stacks-changesets-samples"></a>

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

您可以使用[主控台](using-cfn-updating-stacks-changesets-view.md)、 AWS CLI或 CloudFormation [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeChangeSet.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeChangeSet.html) API 操作來檢視變更集詳細資訊。

為了從堆疊中產生下述各個變更集，此處會採用以下[範例範本](https://s3.amazonaws.com/cloudformation-examples/user-guide/changesets/ec2-instance.txt)：

```
{
  "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" }
          }
        ]
      }
    }
  }
}
```

## 直接編輯範本
<a name="using-cfn-updating-stacks-changesets-samples-directly-editing-a-template"></a>

當您為產生變更集而在堆疊範本中直接修改資源時，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 便無法判斷更新後資源的參考資料是否會改變。

## 修改輸入參數值
<a name="using-cfn-updating-stacks-changesets-samples-modifying-a-single-input-parameter-value"></a>

當您修改輸入參數值時，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` 結構的運作方式，將與其在 [直接編輯範本](#using-cfn-updating-stacks-changesets-samples-directly-editing-a-template) 範例中的運作方式類似。意即該結構僅有一個 `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 欄位的值
<a name="using-cfn-updating-stacks-changesets-samples-determining-the-value-of-the-replacement-field"></a>

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

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

系統會變更每個 `Purpose`、`InstanceType` 和 `KeyPairName` 參數的值，藉此產生下列變更集，而這些參數皆可供 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 替換執行個體的條件，請檢視 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源高達的 `InstanceType` 屬性的更新行為。

## 新增與移除資源
<a name="using-cfn-updating-stacks-changesets-samples-adding-and-removing-resources"></a>

系統將提交修改後的範本，進而產生以下範例；該範本會移除 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 應新增或移除資源。`Scope` 和 `Details` 欄位則沒有內容，因為這些欄位僅適用於修改後的資源。

使用新資源時，您必須執行變更集，否則 CloudFormation 將無法判斷部分欄位的值。例如，由於 Auto Scaling 群組與啟動組態尚不存在，CloudFormation 無法提供這兩者的實體 ID。當您執行變更集時，CloudFormation 即會建立新資源。

## 檢視屬性層級變更
<a name="using-cfn-updating-stacks-changesets-samples-property-level-change-set"></a>

下列範例顯示 Amazon EC2 執行個體屬性的 `Tag` 屬性層級變更。標籤 `Value` 和 `Key` 將變更為 `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` 結構會顯示執行變更集前 `Key` 和 `Value` 的值，以及執行變更集後其預期數值。