

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

# 避免更新堆疊資源
<a name="protect-stack-resources"></a>

當您建立堆疊時，可以對所有的資源執行所有更新動作。根據預設，有堆疊更新許可的任何人都可以更新堆疊中的所有資源。在更新期間，有些資源可能需要中斷或是完全替換，以致產生新的實體 ID 或全新的儲存體。您可避免在使用堆疊政策更新堆疊期間，無意中更新或刪除堆疊資源。堆疊政策是一種 JSON 文件，定義可在指定資源上執行的更新動作。

在您設定堆疊政策之後，堆疊中的所有資源預設都會受到保護。若要允許特定資源的更新，您可以為您堆疊政策中的這些資源指定明確的 `Allow` 陳述式。您每個堆疊只能定義一個堆疊政策，但可以保護單一政策內的多個資源。堆疊政策適用於所有嘗試更新堆疊的 CloudFormation 使用者。您無法建立不同堆疊政策與不同使用者的關聯。

堆疊政策僅適用於堆疊更新期間。此政策不提供類似 AWS Identity and Access Management (IAM) 政策的存取控制。堆疊政策僅作為容錯移轉的安全機制，以避免意外更新特定的堆疊資源。若要控制對 AWS 資源或動作的存取，請使用 IAM。

**Topics**
+ [範例堆疊政策](#stack-policy-intro-example)
+ [定義堆疊政策](#stack-policy-reference)
+ [設定堆疊政策](#protect-stack-resources-protecting)
+ [更新受保護的資源](#protect-stack-resources-updating)
+ [修改堆疊政策](#protect-stack-resources-modifying)
+ [更多範例堆疊政策](#stack-policy-samples)

## 範例堆疊政策
<a name="stack-policy-intro-example"></a>

下列範例堆疊政策會避免更新 `ProductionDatabase` 資源：

```
{
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    },
    {
      "Effect" : "Deny",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "LogicalResourceId/ProductionDatabase"
    }
  ]
}
```

在您設定堆疊政策時，所有資源預設都會受到保護。為允許更新所有資源，我們新增在所有資源上允許所有動作的 `Allow` 陳述式。雖然 `Allow` 陳述式指定所有的資源，但明確的 `Deny` 陳述式會針對邏輯 ID 為 `ProductionDatabase` 的資源覆寫它。此 `Deny` 陳述式會避免 `ProductionDatabase` 資源上所有的更新動作，例如替換或刪除。

`Principal` 元素是必要的，但只支援萬用字元 (`*`)，這表示此陳述式適用於所有[主體](https://docs.aws.amazon.com/glossary/latest/reference/glos-chap.html#principal)。

**注意**  
在堆疊更新期間，CloudFormation 會自動更新依賴其他已更新資源的資源。例如，CloudFormation 會更新參考已更新資源的資源。CloudFormation 不對自動更新的資源 (例如資源 ID) 執行任何實體變更，但如果堆疊政策與這些資源相關聯，您必須有進行更新的許可。

## 定義堆疊政策
<a name="stack-policy-reference"></a>

當您建立堆疊時，未設定任何堆疊政策，所以可對所有的資源執行所有更新動作。為了保護堆疊資源不受更新動作影響，請定義堆疊政策，然後在您的堆疊上設定它。堆疊政策是一種 JSON 文件，可定義 CloudFormation 使用者可以執行的 CloudFormation 堆疊更新動作以及可以套用這些動作的資源。您在建立堆疊時，透過指定包含您堆疊政策的文字檔案或將它輸出的方式，設定堆疊政策。當您在堆疊上設定堆疊政策時，預設拒絕任何未明確允許的更新。

您可以使用五種元素定義堆疊政策：`Effect`、`Action`、`Principal`、`Resource` 和 `Condition`。下列虛擬程式碼顯示堆疊政策的語法。

```
{
  "Statement" : [
    {
      "Effect" : "Deny_or_Allow",
      "Action" : "update_actions",
      "Principal" : "*",
      "Resource" : "LogicalResourceId/resource_logical_ID",
      "Condition" : {
        "StringEquals_or_StringLike" : {
          "ResourceType" : [resource_type, ...]
        }
      }
    }
  ]
}
```

`Effect`  
決定在您指定的資源上拒絕或允許您指定的動作。您只能指定 `Deny` 或 `Allow`，例如：  

```
"Effect" : "Deny"
```
如果堆疊政策包含重疊的陳述式 (允許和拒絕對資源的更新)，則 `Deny` 陳述式一律會覆寫 `Allow` 陳述式。為了確保資源受到保護，請為該資源使用 `Deny` 陳述式。

Action  
指定拒絕或允許的更新動作：    
Update:Modify  
指定在其執行期間，資源可能不會中斷，或套用變更時有些中斷的更新動作。所有資源都保持它們的實體 ID。  
Update:Replace  
指定在其執行期間，會重新建立資源的更新動作。CloudFormation 使用指定的更新建立新資源，然後刪除舊資源。由於資源是重新建立的，所以新資源的實體 ID 可能不同。  
Update:Delete  
指定在其執行期間，會移除資源的更新動作。從堆疊範本完全移除資源的更新，需要此動作。  
更新:\$1  
指定所有更新動作。星號是萬用字元，代表所有更新動作。
下列範例說明如何只指定取代和刪除動作：  

```
"Action" : ["Update:Replace", "Update:Delete"]
```
若要允許某個除外的所有更新動作，請使用 `NotAction`。例如，若要允許 `Update:Delete` 除外的所有更新動作，請使用 `NotAction`，如這個範例所示：  

```
{
  "Statement" : [
    {
      "Effect" : "Allow",
      "NotAction" : "Update:Delete",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```

Principal  
`Principal` 元素指定套用政策的實體。此元素是必要的，但只支援萬用字元 (`*`)，這表示政策適用於所有[主體](https://docs.aws.amazon.com/glossary/latest/reference/glos-chap.html#principal)。

資源  
指定套用政策的資源邏輯 ID。若要指定資源類型，請使用 `Condition`元素。  
若要指定單一資源，請使用它的邏輯 ID。例如：  

```
"Resource" : ["LogicalResourceId/myEC2instance"]
```
邏輯 ID 可以使用萬用字元。例如，如果所有相關資源都使用常見的邏輯 ID 字首，您可以用萬用字元指定它們全部：  

```
"Resource" : ["LogicalResourceId/CriticalResource*"]
```
資源也可以使用 `Not` 元素。例如，若要允許某個以外的所有資源更新，請使用 `NotResource` 元素來保護該資源：  

```
{
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "NotResource" : "LogicalResourceId/ProductionDatabase"
    }
  ]
}
```
當您設定堆疊政策時，預設拒絕任何未明確允許的更新。透過允許 `ProductionDatabase` 資源以外的所有資源更新，您拒絕更新 `ProductionDatabase` 資源。

條件  
指定套用政策的資源類型。若要指定特定資源的邏輯 ID，請使用 `Resource` 元素。  
您可以指定資源類型，例如所有 EC2 和 RDS 資料庫執行個體，如下列範例所示：  

```
{
  "Statement" : [
  {
    "Effect" : "Deny",
    "Principal" : "*",
    "Action" : "Update:*",
    "Resource" : "*",
    "Condition" : {
      "StringEquals" : {
        "ResourceType" : ["AWS::EC2::Instance", "AWS::RDS::DBInstance"]
      }
    }
  },
  {
    "Effect" : "Allow",
    "Principal" : "*",
    "Action" : "Update:*",
    "Resource" : "*"
  }
  ]
}
```
`Allow` 陳述式將更新許可授予所有資源，而 `Deny` 陳述式拒絕更新 EC2 和 RDS 資料庫執行個體。`Deny` 陳述式一律會覆寫允許動作。  
資源類型可以使用萬用字元。例如，您可以使用萬用字元拒絕所有 Amazon EC2 資源的更新許可 —例如執行個體、安全群組和子網路— 如下列範例所示：  

```
"Condition" : {
  "StringLike" : {
    "ResourceType" : ["AWS::EC2::*"]
  }
}
```
使用萬用字元時，您必須使用 `StringLike` 條件。

## 設定堆疊政策
<a name="protect-stack-resources-protecting"></a>

您可以使用 主控台 AWS CLI 或在建立堆疊時套用堆疊政策。您也可以使用 AWS CLI 將堆疊政策套用至現有堆疊。套用堆疊政策後，您無法將其從堆疊中移除，但您可以使用 AWS CLI 進行修改。

堆疊政策適用於所有嘗試更新堆疊的 CloudFormation 使用者。您無法建立不同堆疊政策與不同使用者的關聯。

如需撰寫堆疊政策的資訊，請參閱[定義堆疊政策](#stack-policy-reference)。

**在建立堆疊時設定堆疊政策 (主控台)**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 在畫面頂端的導覽列上，選擇要在其中 AWS 區域 建立堆疊的 。

1. 在 **CloudFormation Stacks (CloudFormation 堆疊)** 頁面上，選擇 **Create stack (建立堆疊)**。

1. 在 Create Stack (建立堆疊) 精靈的 **Configure stack options (設定堆疊選項)** 頁面上，展開 **Advanced (進階)** 區段，然後選擇 **Stack policy (堆疊政策)**。

1. 指定堆疊政策：
   + 若要直接在主控台中編寫政策，請選擇 **Enter stack policy (輸入堆疊政策)**，然後直接在文字欄位中輸入堆疊政策。
   + 若要使用其他檔案定義的政策，請選擇 **Upload a file (上傳檔案)**，然後選擇 **Choose file (選擇檔案)**，選取包含堆疊政策的檔案。

**在建立堆疊時設定堆疊政策 (AWS CLI)**
+ 使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html) 命令搭配 `--stack-policy-body` 選項輸入修改的政策，或搭配 `--stack-policy-url` 選項指定包含政策的檔案。

**在現有堆疊上設定堆疊政策 (AWS CLI 僅限 )**
+ 使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-stack-policy.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-stack-policy.html) 命令搭配 `--stack-policy-body` 選項輸入修改的政策，或搭配 `--stack-policy-url` 選項指定包含政策的檔案。
**注意**  
若要將政策新增到現有的堆疊，您必須擁有 CloudFormation [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html) 動作的許可。

## 更新受保護的資源
<a name="protect-stack-resources-updating"></a>

若要更新受保護的資源，請建立覆寫堆疊政策的暫時政策，並允許更新這些資源。在更新堆疊時您指定覆寫政策。覆寫的政策不會永久變更堆疊政策。

若要更新受保護的資源，您必須有使用 CloudFormation [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html) 動作的許可。如需設定 CloudFormation 許可的資訊，請參閱[使用 控制 CloudFormation 存取 AWS Identity and Access Management](control-access-with-iam.md)。

**注意**  
在堆疊更新期間，CloudFormation 會自動更新依賴其他已更新資源的資源。例如，CloudFormation 會更新參考已更新資源的資源。CloudFormation 不對自動更新的資源 (例如資源 ID) 執行任何實體變更，但如果堆疊政策與這些資源相關聯，您必須有進行更新的許可。

**更新受保護的資源 (主控台)**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

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

1. 如「尚未」**修改堆疊範本，請選取 **Use current template (使用目前的範本)**，然後按一下 **Next (下一步)**。如已修改範本，請選取 **Replace current template (取代目前的範本)**，然後在 **Specify template (指定範本)** 區段中指定更新的範本位置：
   + 如果是存放在本機電腦上的範本，請選取 **Upload a template file (上傳範本檔案)**。選擇 **Choose File** (選擇檔案) 以瀏覽至該檔案，然後按一下 **Next** (下一步)。
   + 如需存放在 Amazon S3 儲存貯體的範本，請選取 **Amazon S3 URL**。輸入或貼上範本的 URL，然後按一下 **Next** (下一步)。

     如果您擁有已啟用版本控制的儲存貯體中的範本，則可以指定範本的特定版本，方法是將 `?versionId=version-id` 附加到 URL。如需詳細資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[使用已啟用版本控制之儲存貯體中的物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/manage-objects-versioned-bucket.html)。

1. 如果您的範本包含參數，請在 **Specify stack details (指定堆疊詳細資訊)** 頁面上輸入或修改參數值，然後選擇 **Next (下一步)**。

   CloudFormation 以堆疊中目前設定的值填入每個參數，但以 `NoEcho` 屬性宣告的參數除外。您可以選擇 **Use existing value (使用現有的值)**，為這些參數使用目前的值。

   如需使用 `NoEcho` 遮罩敏感資訊，以及使用動態參數管理密碼的詳細資訊，請參閱 [請勿在您的範本中內嵌憑證](security-best-practices.md#creds) 最佳實務。

1. 指定覆寫堆疊政策。

   1. 在 **Configure stack options (設定堆疊選項)** 頁面的 **Advanced options (進階選項)** 區段中，選取 **Stack policy (堆疊政策)**。

   1. 選取 **Upload a file (上傳檔案)**。

   1. 按一下 **Choose file (選擇檔案)**，導覽至包含覆寫堆疊政策的檔案，或輸入政策。

   1. 選擇**下一步**。

   覆寫政策必須為您要更新的受保護資源指定 `Allow` 陳述式。例如，若要更新所有受保護的資源，請指定允許所有更新的暫時覆寫政策：

   ```
   {
     "Statement" : [
       {
         "Effect" : "Allow",
         "Action" : "Update:*",
         "Principal": "*",
         "Resource" : "*"
       }
     ]
   }
   ```
**注意**  
CloudFormation 只會在此更新期間套用覆寫政策。覆寫的政策不會永久變更堆疊政策。若要修改堆疊政策，請參閱[修改堆疊政策](#protect-stack-resources-modifying)。

1. 檢閱堆疊資訊和您提交的變更。

   檢查是否提交了正確的資訊，例如正確的參數值或範本 URL。如果您的範本包含 IAM 資源，請選擇 **I acknowledge that this template may create IAM resources (我知道此範本可能會建立 IAM 資源)** 以指定您要使用此範本中的 IAM 資源。如需詳細資訊，請參閱[認可 CloudFormation 範本中的 IAM 資源](control-access-with-iam.md#using-iam-capabilities)。

   在**預覽您的變更**區段中，檢查 CloudFormation 是否將會進行您預期的所有變更。例如，檢查 CloudFormation 是否會新增、移除及修改您要新增、移除或修改的資源。CloudFormation 透過建立針對堆疊設定的變更，產生此預覽。如需詳細資訊，請參閱[透過變更集更新 CloudFormation 堆疊](using-cfn-updating-stacks-changesets.md)。

1. 當您完成變更後，請按一下 **Update (更新)**。
**注意**  
此時，您也可以選擇檢視變更集，更仔細地檢閱您提出的更新。若要執行此動作，請按一下 **View change set** (檢視變更集) 而不是 **Update** (更新)。CloudFormation 會顯示根據更新所產生的變更集。當您準備好執行堆疊更新時，請按一下 **Execute (執行)**。

   CloudFormation 會顯示您堆疊的 **Stack details (堆疊詳細資訊)** 頁面。您的堆疊目前的狀態為 `UPDATE_IN_PROGRESS`。CloudFormation 成功更新堆疊之後，就會將堆疊狀態設為 `UPDATE_COMPLETE`。

   如果堆疊更新失敗，CloudFormation 會自動復原變更，並將堆疊狀態設為 `UPDATE_ROLLBACK_COMPLETE`。

**更新受保護的資源 (AWS CLI)**
+ 使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/update-stack.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/update-stack.html) 命令搭配 `--stack-policy-during-update-body` 選項輸入修改的政策，或搭配 `--stack-policy-during-update-url` 選項指定包含政策的檔案。
**注意**  
CloudFormation 只會在此更新期間套用覆寫政策。覆寫的政策不會永久變更堆疊政策。若要修改堆疊政策，請參閱[修改堆疊政策](#protect-stack-resources-modifying)。

## 修改堆疊政策
<a name="protect-stack-resources-modifying"></a>

若要保護其他資源或移除對資源的保護，請修改堆疊政策。例如，當您將想要保護的資料庫新增到您的堆疊時，請為該資料庫將 `Deny` 陳述式新增到堆疊政策。若要修改政策，您必須有使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html) 動作的許可。

使用 AWS CLI 修改堆疊政策。

**修改堆疊政策 (AWS CLI)**
+ 使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-stack-policy.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-stack-policy.html) 命令搭配 `--stack-policy-body` 選項輸入修改的政策，或搭配 `--stack-policy-url` 選項指定包含政策的檔案。

您無法刪除堆疊政策。若要移除所有資源的所有保護，您要修改政策，明確允許對所有資源的所有動作。下列政策允許所有資源的所有更新：

```
{
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```

## 更多範例堆疊政策
<a name="stack-policy-samples"></a>

下列範例政策示範如何防止更新所有堆疊資源和特定資源，並防止特定類型的更新。

### 避免更新所有堆疊資源
<a name="w2aac43c15c21b5"></a>

為了防止更新所有堆疊資源，下列政策為所有資源的所有更新動作指定 `Deny` 陳述式。

```
{
  "Statement" : [
    {
      "Effect" : "Deny",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```

### 避免更新單一資源
<a name="w2aac43c15c21b7"></a>

下列政策拒絕邏輯 ID 為 `MyDatabase` 之資料庫的所有更新動作。`Allow` 陳述式允許所有其他堆疊資源的所有更新動作。`Allow` 陳述式不適用於 `MyDatabase` 資源，因為 `Deny` 陳述式一律會覆寫允許動作。

```
{
  "Statement" : [
    {
      "Effect" : "Deny",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "LogicalResourceId/MyDatabase"
    },
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```

使用預設拒絕可以達到和前例相同的結果。當您設定堆疊政策時，CloudFormation 拒絕任何未明確允許的更新。下列政策允許更新所有資源，預設拒絕的 `ProductionDatabase` 資源除外。

```
{
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "NotResource" : "LogicalResourceId/ProductionDatabase"
    }
  ]
}
```

**重要**  
使用預設拒絕有風險。如果政策的其他位置有一個 `Allow` 陳述式 (例如使用萬用字元的 `Allow` 陳述式)，您可能會在不知情的狀況下將更新許可授予您不打算更新的資源。由於明確拒絕會覆寫任何允許動作，所以您可以使用 `Deny` 陳述式確保資源受到保護。

### 避免更新某種資源類型的所有執行個體
<a name="w2aac43c15c21b9"></a>

下列政策拒絕 RDS 資料庫執行個體資源類型的所有更新動作。`Allow` 陳述式允許所有其他堆疊資源的所有更新動作。`Allow` 陳述式不適用於 RDS 資料庫執行個體資源，因為 `Deny` 陳述式一律會覆寫允許動作。

```
{
  "Statement" : [
    {
      "Effect" : "Deny",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*",
      "Condition" : {
        "StringEquals" : {
          "ResourceType" : ["AWS::RDS::DBInstance"]
        }
      }
    },
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```

### 避免更換執行個體的更新
<a name="w2aac43c15c21c11"></a>

下列政策拒絕會造成更換邏輯 ID 為 `MyInstance` 之執行個體的更新。`Allow` 陳述式允許所有其他堆疊資源的所有更新動作。`Allow` 陳述式不適用於 `MyInstance` 資源，因為 `Deny` 陳述式一律會覆寫允許動作。

```
{
  "Statement" : [
    {
      "Effect" : "Deny",
      "Action" : "Update:Replace",
      "Principal": "*",
      "Resource" : "LogicalResourceId/MyInstance"
    },
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```

### 避免巢狀堆疊的更新
<a name="w2aac43c15c21c13"></a>

下列政策拒絕 CloudFormation 堆疊資源類型 (巢狀堆疊) 的所有更新動作。`Allow` 陳述式允許所有其他堆疊資源的所有更新動作。`Allow` 陳述式不適用於 CloudFormation 堆疊資源，因為 `Deny` 陳述式一律會覆寫允許動作。

```
{
  "Statement" : [
    {
      "Effect" : "Deny",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*",
      "Condition" : {
        "StringEquals" : {
          "ResourceType" : ["AWS::CloudFormation::Stack"]
        }
      }
    },
    {
      "Effect" : "Allow",
      "Action" : "Update:*",
      "Principal": "*",
      "Resource" : "*"
    }
  ]
}
```