

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

# 選擇佈建資源時的失敗處理方式
<a name="stack-failure-options"></a>

若您的堆疊操作失敗，則不必每次都復原已成功佈建的資源，並從頭開始。反之，您可以對處於 `CREATE_FAILED` 或 `UPDATE_FAILED` 狀態的資源疑難排解，然後從問題發生點繼續佈建。

要這樣做，您必須啟用保留成功佈建的資源選項。此選項適用於所有堆疊部署和變更集操作。
+ 建立堆疊時，若選擇**保留成功佈建資源**選項，CloudFormation 會保留成功建立之資源的狀態，並將失敗的資源保持在失敗狀態，直到執行下次更新操作為止。
+ 在更新與變更集操作期間，**保留已成功佈建的資源**選項可保留成功資源的狀態，同時將失敗資源復原到上一個已知穩定狀態。失敗的資源將處於 `UPDATE_FAILED` 狀態。沒有上一個已知穩定狀態的資源將在下一次堆疊操作時遭刪除。

**Topics**
+ [堆疊失敗選項概觀](#stack-failure-options-overview)
+ [暫停堆疊復原的必要條件](#stack-failure-options-conditions)
+ [保留已成功佈建的資源 (主控台)](#stack-failure-options-console)
+ [保留已成功佈建的資源 (AWS CLI)](#stack-failure-options-cli)

## 堆疊失敗選項概觀
<a name="stack-failure-options-overview"></a>

從 CloudFormation 主控台、API 或 發出 操作之前 AWS CLI，請指定佈建資源失敗的行為。然後，繼續進行資源的部署過程，而無需進行任何其他修改。在操作失敗的情況下，CloudFormation 會在每個獨立佈建路徑中的第一次失敗時停止。CloudFormation 可識別資源之間的相依性，以平行化獨立佈建動作。然後，它會繼續在每個獨立佈建路徑上佈建資源，直到遇到失敗為止。一個路徑中的失敗不會影響其他佈建路徑。CloudFormation 將繼續佈建資源，直到完成或在遇到其他失敗時停止。

修復任何問題以繼續部署程序。在早些時候無法成功佈建的資源上重試佈建動作之前，CloudFormation 會先執行必要的更新。您可以透過提交 **Retry** (重試)、**Update** (更新) 或 **Roll back** (復原) 操作來修復問題。例如，如果您要佈建 Amazon EC2 執行個體，且 EC2 執行個體在建立操作期間失敗，您可能需要調查錯誤，而不是立即復原失敗的資源。您可以檢閱系統狀態檢查和執行個體狀態檢查，一旦問題得到解決，選取 **Retry** (重試) 操作。

當堆疊操作失敗，並且您已經從 **Stack failure options** (堆疊失敗選項) 選單指定 **Preserve successfully provisioned resources** (保留已成功佈建的資源) 時，您可以選取下列選項。
+ **Retry** (重試) – 在失敗的資源上重試佈建操作，並繼續佈建範本，直到成功完成堆疊操作或下一次失敗為止。如果資源因為不需要修改範本的問題而無法佈建，例如 AWS Identity and Access Management (IAM) 許可，請選取此選項。
+ **Update** (更新) – 已佈建的資源會在範本更新時更新。將重試建立或更新失敗的資源。如果資源因範本錯誤而無法佈建，且您已修改範本，請選取此選項。當您更新狀態為 `FAILED` 的堆疊時，您必須針對 **Stack failure options** (堆疊失敗選項) 選取 **Preserve successfully provisioned resources** (保留已成功佈建的資源)，以繼續更新您的堆疊。
+ **Roll back** (復原) – CloudFormation 會將堆疊復原到上一個已知穩定狀態。

## 暫停堆疊復原的必要條件
<a name="stack-failure-options-conditions"></a>

要防止 CloudFormation 自動復原和刪除已成功建立的資源，必須符合下列條件。

1. 建立或更新堆疊時，您必須選擇**保留成功佈建資源**的選項。這會告知 CloudFormation，即使整體堆疊操作失敗，也不要刪除已成功建立的資源。

1. 堆疊操作必須已失敗，即堆疊狀態為 `CREATE_FAILED` 或 `UPDATE_FAILED`。

**注意**  
不支援不可變更新類型。

## 保留已成功佈建的資源 (主控台)
<a name="stack-failure-options-console"></a>

------
#### [ Create stack ]

**在建立堆疊操作期間保留已成功佈建的資源**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 從**堆疊**頁面的右上角，選擇**建立堆疊**，並選擇**使用新資源 (標準)**。

1. 對於**先決條件 - 準備範本**，選取**選擇現有範本**。

1. 在 **Specify template (指定範本)** 下，選擇指定堆疊範本所在 S3 儲存貯體的 URL，或上傳堆疊範本檔案。然後選擇**下一步**。

1. 在 **Specify stack details** (指定堆疊詳細資訊) 頁面上，在 **Stack name** (堆疊名稱) 方塊中輸入堆疊名稱。

1. 在 **Parameters** (參數) 部分中，指定堆疊範本中定義的參數。

   您可以用預設值來使用或變更任何參數。

1. 當您滿意參數值時，請選擇 **Next** (下一步)。

1. 在 **Configure stack options** (設定堆疊選項) 頁面上，您可以設定堆疊的其他選項。

1. 對於 **Stack failure options** (堆疊失敗選項)，請選取 **Preserve successfully provisioned resources** (保留已成功佈建的資源)。

1. 當您滿意堆疊選項時，請選擇 **Next** (下一步)。

1. 在 **Review** (檢閱) 頁面上檢閱您的堆疊並選取 **Create stack** (建立堆疊)。

*結果*：建立失敗的堆疊會將堆疊狀態轉換為 `CREATE_FAILED`，以防止堆疊在堆疊操作遭遇失敗時復原。已成功佈建的資源處於 `CREATE_COMPLETE` 狀態。您可以在 **Stack events** (堆疊事件) 索引標籤中監控堆疊。

------
#### [ Update stack ]

**在更新堆疊操作期間保留已成功佈建的資源**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選取您希望更新的堆疊，然後選擇 **Update** (更新)。

1. 在 **Update stack** (更新堆疊) 頁面上，使用下列其中一個選項選擇堆疊範本：
   + **使用現有範本**
   + **Replace current template** (取代目前範本)
   + **在 Infrastructure Composer 中編輯範本**

   接受您的設定並選取 **Next** (下一步)。

1. 在 **Specify stack details** (指定堆疊詳細資訊) 頁面上，指定堆疊範本中所定義的參數。

   您可以用預設值來使用或變更任何參數。

1. 當您滿意參數值時，請選擇 **Next** (下一步)。

1. 在 **Configure stack options** (設定堆疊選項) 頁面上，您可以設定堆疊的其他選項。

1. 對於 **Behavior on provisioning failure** (佈建失敗時的行為)，選取 **Preserve successfully provisioned resources** (保留已成功佈建的資源)。

1. 當您滿意堆疊選項時，請選擇 **Next** (下一步)。

1. 在 **Review** (檢閱) 頁面上檢閱您的堆疊並選取 **Update stack** (更新堆疊)。

*結果*：更新失敗的堆疊會將狀態轉換為 `UPDATE_FAILED`，並復原到上一個已知穩定狀態。沒有上一個已知穩定狀態的資源將在下一次堆疊操作時由 CloudFormation 刪除。已成功佈建的資源處於 `CREATE_COMPLETE` 或 `UPDATE_COMPLETE` 狀態。您可以在 **Stack events** (堆疊事件) 索引標籤中監控堆疊。

------
#### [ Change set ]

**注意**  
您可以為狀態為 `CREATE_FAILED` 或 `UPDATE_FAILED` 的堆疊啟動變更集，但不適用於狀態 `UPDATE_ROLLBACK_FAILED`。

**在變更集操作期間保留已成功佈建的資源**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選取包含您要啟動的變更集的堆疊，然後選擇 **Change sets** (變更集) 索引標籤。

1. 選取變更集，然後選擇 **Execute** (執行)。

1. 對於 **Execute change set** (執行變更集)，選取 **Preserve successfully provisioned resources** (保留已成功佈建的資源) 選項。

1. 選取 **Execute change set** (執行變更集)。

*結果*：更新失敗的堆疊會將狀態轉換為 `UPDATE_FAILED`，並復原到上一個已知穩定狀態。沒有上一個已知穩定狀態的資源將在下一次堆疊操作時由 CloudFormation 刪除。已成功佈建的資源處於 `CREATE_COMPLETE` 或 `UPDATE_COMPLETE` 狀態。您可以在 **Stack events** (堆疊事件) 索引標籤中監控堆疊。

------

## 保留已成功佈建的資源 (AWS CLI)
<a name="stack-failure-options-cli"></a>

------
#### [ Create stack ]

**在堆疊建立操作期間保留已成功佈建的資源**

指定 [create-stack](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html) 操作期間的 `--disable-rollback` 選項或 `on-failure DO_NOTHING` 列舉。

1. 使用 `--disable-rollback` 選項向 **create-stack** 命令提供堆疊名稱和範本。

   ```
   aws cloudformation create-stack --stack-name myteststack \
       --template-body file://template.yaml \
       --disable-rollback
   ```

   命令會傳回下列輸出：

   ```
   {
       "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896"
   }
   ```

1. 使用 **describe-stacks** 命令描述堆疊的狀態。

   ```
   aws cloudformation describe-stacks --stack-name myteststack
   ```

   命令會傳回下列輸出：

   ```
   {
       "Stacks":  [
           {
               "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896",
               "Description": "AWS CloudFormation Sample Template",
               "Tags": [],
               "Outputs": [],
               "StackStatusReason": “The following resource(s) failed to create: [MyBucket]”,
               "CreationTime": "2013-08-23T01:02:15.422Z",
               "Capabilities": [],
               "StackName": "myteststack",
               "StackStatus": "CREATE_FAILED",
               "DisableRollback": true
           }
       ]
   }
   ```

------
#### [ Update stack ]

**在更新堆疊操作期間保留已成功佈建的資源**

1. 使用 `--disable-rollback` 選項向 **update-stack** 命令提供現有堆疊名稱和範本。

   ```
   aws cloudformation update-stack --stack-name myteststack \
       --template-url https://s3.amazonaws.com/amzn-s3-demo-bucket/updated.template --disable-rollback
   ```

   命令會傳回下列輸出：

   ```
   {
       "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896"
   }
   ```

1. 使用 **describe-stacks** 或 **describe-stack-events** 選項描述堆疊的狀態。

   ```
   aws cloudformation describe-stacks --stack-name myteststack
   ```

   命令會傳回下列輸出：

   ```
   {
       "Stacks":  [
           {
               "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896",
               "Description": "AWS CloudFormation Sample Template",
               "Tags": [],
               "Outputs": [],
               "CreationTime": "2013-08-23T01:02:15.422Z",
               "Capabilities": [],
               "StackName": "myteststack",
               "StackStatus": "UPDATE_COMPLETE",
               "DisableRollback": true
           }
       ]
   }
   ```

------
#### [ Change set ]

**注意**  
您可以為狀態為 `CREATE_FAILED` 或 `UPDATE_FAILED` 的堆疊啟動變更集，但不適用於狀態 `UPDATE_ROLLBACK_FAILED`。

**在變更集操作期間保留已成功佈建的資源**

指定 [execute-change-set](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/execute-change-set.html) 操作期間的 `--disable-rollback` 選項。

1. 使用 `--disable-rollback` 選項向 **execute-change-set** 命令提供堆疊名稱和範本。

   ```
   aws cloudformation execute-change-set --stack-name myteststack \
       --change-set-name my-change-set --template-body file://template.yaml
   ```

   命令會傳回下列輸出：

   ```
   {
    "Id": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/my-change-set/bc9555ba-a949-xmpl-bfb8-f41d04ec5784",
    "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896"
   }
   ```

1. 使用 `--disable-rollback` 選項啟動變更集。

   ```
   aws cloudformation execute-change-set --stack-name myteststack \
       --change-set-name my-change-set -–disable-rollback
   ```

1. 使用 **describe-stacks** 或 **describe-stack-events** 選項判斷堆疊的狀態。

   ```
   aws cloudformation describe-stack-events --stack-name myteststack
   ```

   命令會傳回下列輸出：

   ```
   {
      "StackEvents": [
        {
           "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896",
           "EventId": "49c966a0-7b74-11ea-8071-024244bb0672",
           "StackName": "myteststack",
           "LogicalResourceId": " MyBucket",
           "PhysicalResourceId": "myteststack-MyBucket-abcdefghijk1",
           "ResourceType": "AWS::S3::Bucket",
           "Timestamp": "2020-04-10T21:43:17.015Z",
           "ResourceStatus": "UPDATE_FAILED"
           "ResourceStatusReason": "User XYZ is not allowed to perform S3::UpdateBucket on MyBucket"
        }
   }
   ```

1. 修正許可錯誤，然後重試操作。

   ```
   aws cloudformation update-stack --stack-name myteststack \
       --use-previous-template --disable-rollback
   ```

   命令會傳回下列輸出：

   ```
   {
       "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896"
   }
   ```

1. 使用 **describe-stacks** 或 **describe-stack-events** 選項描述堆疊的狀態。

   ```
   aws cloudformation describe-stacks --stack-name myteststack
   ```

   命令會傳回下列輸出：

   ```
   {
       "Stacks":  [
           {
               "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896",
               "Description": "AWS CloudFormation Sample Template",
               "Tags": [],
               "Outputs": [],
               "CreationTime": "2013-08-23T01:02:15.422Z",
               "Capabilities": [],
               "StackName": "myteststack",
               "StackStatus": "UPDATE_COMPLETE",
               "DisableRollback": true
           }
       ]
   }
   ```

------

### 復原堆疊
<a name="roll-back-stack-cli"></a>

您可使用 [rollback-stack](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/rollback-stack.html) 命令，將具有 `CREATE_FAILED` 或 `UPDATE_FAILED` 堆疊狀態的堆疊復原至其最後穩定狀態。

下列 **rollback-stack** 命令會復原指定的堆疊。

```
aws cloudformation rollback-stack --stack-name myteststack
```

命令會傳回下列輸出：

```
{
    "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896"
}
```

**注意**  
如果堆疊不包含上一個已知穩定狀態，**rollback-stack** 操作將刪除堆疊。