

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

# 在 CloudFormation 範本中建立等待條件
<a name="using-cfn-waitcondition"></a>

此主題解釋了如何在範本中建立等待條件可協調堆疊資源的建立，或追蹤組態程序的進度。例如，您可以在應用程式組態完成一部分後，開始建立另一個資源，或是在安裝和組態程序期間傳送訊號來追蹤其進度。

在 CloudFormation 建立包含等待條件的堆疊時：
+ 它像任何其他資源一樣建立等待條件，並將等待條件的狀態設定為 `CREATE_IN_PROGRESS`。
+ CloudFormation 會等待，直到收到所需數量的成功訊號，或等待條件的逾時時間到期。
+ 若在逾時時間到期前收到所需數量的成功訊號：
  + 等待條件狀態變更為 `CREATE_COMPLETE`
  + 堆疊建立繼續
+ 如果逾時過期，或收到失敗訊號：
  + 等待條件狀態變更為 `CREATE_FAILED`
  + 堆疊復原

**重要**  
針對 Amazon EC2 和 Auto Scaling 資源，我們建議您使用 CreationPolicy 屬性，而非等待條件。請將 CreationPolicy 屬性新增至這類資源，並使用 cfn-signal 的 helper 指令碼在執行個體建立流程成功完成後發出訊號。  
如需詳細資訊，請參閱 [CreationPolicy 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-creationpolicy.html)。

**注意**  
如果您使用 AWS PrivateLink，VPC 中回應等待條件的資源必須能夠存取 CloudFormation 特定的 Amazon Simple Storage Service (Amazon S3) 儲存貯體。資源必須傳送等待條件回應至預先簽章的 Amazon S3 URL。若無法將回應傳送至 Amazon S3，CloudFormation 便不會收到回應，而堆疊操作則會失敗。如需詳細資訊，請參閱 [CloudFormation 使用界面端點存取 (AWS PrivateLink)](vpc-interface-endpoints.md) 和[使用儲存貯體政策控制 VPC 端點的存取](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies-vpc-endpoint.html)。

**Topics**
+ [在您的範本中建立等待條件](#creating-wait-condition)
+ [等待條件訊號語法](#wait-condition-signal-syntax)
+ [存取訊號資料](#wait-condition-access-signal-data)

## 在您的範本中建立等待條件
<a name="creating-wait-condition"></a>

**1. 等待條件控點**  
首先在堆疊的範本中定義 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitconditionhandle.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitconditionhandle.html) 資源。此資源會產生傳送訊號所需的預先簽章 URL。這可讓您傳送訊號，無需提供您的 AWS 憑證。例如：

```
Resources:
  MyWaitHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
```

**2. 等待條件**  
接下來，您可在堆疊的範本中定義 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitcondition.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitcondition.html) 資源。`AWS::CloudFormation::WaitCondition` 的基本結構如下所示：

```
  MyWaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    Properties:
      Handle: String
      Timeout: String
      Count: Integer
```

`AWS::CloudFormation::WaitCondition` 資源有兩個必要屬性和一個選用屬性。
+ `Handle` (必要) – 範本中所宣告 `WaitConditionHandle` 的參考。
+ `Timeout` (必要) – CloudFormation 等待收到必要訊號數的秒數。`Timeout` 是最小限制屬性，表示逾時不會早於您指定的時間，但會在之後不久發生。您可以指定的時間上限是 43200 秒 (12 小時)。
+ `Count` (選用) – CloudFormation 在將等待條件的狀態設定為 `CREATE_COMPLETE` 之前，必須接收的成功訊號數量，並繼續建立堆疊。如果未指定，預設值為 1。

通常，您會希望等待條件在特定資源建立完成後立即開始。您可以將 `DependsOn` 屬性新增至等待條件來執行此操作。向等待條件新增 `DependsOn` 屬性後，CloudFormation 會先建立 `DependsOn` 屬性中指定的資源，再建立等待條件。如需詳細資訊，請參閱 [DependsOn 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-dependson.html)。

下列範例示範的等待條件如下：
+ 在成功建立 `MyEC2Instance` 資源後開始
+ 將 `MyWaitHandle` 資源用作 `WaitConditionHandle`
+ 逾時時間為 4500 秒
+ 預設 `Count` 為 1 (因為未指定 `Count` 屬性)

```
  MyWaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    DependsOn: MyEC2Instance
    Properties:
      Handle: !Ref MyWaitHandle
      Timeout: '4500'
```

**3. 傳送訊號**  
若要向 CloudFormation 傳出成功或失敗訊號，您通常會執行一些程式碼或指令碼。例如，在 EC2 執行個體上執行的應用程式可能會執行一些額外的組態工作，然後向 CloudFormation 傳送訊號以表示完成。

訊號必須傳送至等待條件控制代碼產生的預先簽章 URL。使用預先簽章的 URL 傳送成功或失敗訊號。

**傳送訊號**

1. 要擷取範本中的預先簽章 URL，請使用 `Ref` 內建函數搭配等待條件控點的邏輯名稱。

   如以下範例所示，您的範本可以宣告 Amazon EC2 執行個體，並透過 Amazon EC2 `UserData` 屬性將預先簽章的 URL 傳遞至 Amazon EC2 執行個體。這讓在這些執行個體上執行的指令碼或應用程式能向 CloudFormation 傳送成功或失敗訊號。

   ```
     MyEC2Instance:
       Type: AWS::EC2::Instance
       Properties:
       InstanceType: t2.micro  # Example instance type
       ImageId: ami-055e3d4f0bbeb5878  # Change this as needed (Amazon Linux 2023 in us-west-2)
       UserData:
         Fn::Base64: 
           Fn::Join: 
             - ""
             - - "SignalURL="
               - { "Ref": "MyWaitHandle" }
   ```

   這導致 `UserData` 輸出結果類似以下內容：

   ```
   SignalURL=https://amzn-s3-demo-bucket.s3.amazonaws.com/....
   ```

   注意：在 AWS 管理主控台 和命令列工具中，預先簽章的 URL 會顯示為等待條件處理資源的實體 ID。

1. (選用) 若要偵測堆疊何時進入等待條件，您可以使用下列其中一種方法：
   + 如果您建立堆疊並啟用通知，CloudFormation 會針對每個堆疊事件發佈通知到指定的主題。如果您或您的應用程式訂閱該主題，您可以監控等待條件控點建立事件的通知，並從通知訊息擷取預先簽章的 URL。
   + 您也可以使用 AWS 管理主控台、 AWS CLI或 SDK 來監控堆疊的事件。

1. 若要傳送訊號，您可以使用預先簽章的 URL 傳送 HTTP 請求訊息。請求方法必須是 `PUT`，而且 `Content-Type` 標頭必須是空白字串或予以省略。請求訊息必須是 [等待條件訊號語法](#wait-condition-signal-syntax) 中指定格式的 JSON 結構。

   您必須傳送 `Count` 屬性指定的成功訊號數目，CloudFormation 才能繼續建立堆疊。如果您的 `Count` 大於 1，在傳送至特定等待條件的所有訊號之間，每個訊號的 `UniqueId` 值必須都是不重複的。`UniqueId` 是任意英數字串。

   `curl` 命令是傳送訊號的一種方式。下列範例示範將成功訊號傳送至等待條件的 `curl` 命令列。

   ```
   $ curl -T /tmp/a \
     "https://amzn-s3-demo-bucket.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"
   ```

   其中 *`/tmp/a`* 檔案包含下列 JSON 結構：

   ```
   {
      "Status" : "SUCCESS",
      "Reason" : "Configuration Complete",
      "UniqueId" : "ID1234",
      "Data" : "Application has completed configuration."
   }
   ```

   此範例示範傳送同一個成功訊號的 `curl` 命令列，差別在於在命令列中以參數的形式傳送 JSON 結構。

   ```
   $ curl -X PUT \
     -H 'Content-Type:' --data-binary '{"Status" : "SUCCESS","Reason" : "Configuration Complete","UniqueId" : "ID1234","Data" : "Application has completed configuration."}' \
     "https://amzn-s3-demo-bucket.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"
   ```

## 等待條件訊號語法
<a name="wait-condition-signal-syntax"></a>

當您向等候條件控點所產生的 URL 傳送訊號時，您必須使用下列 JSON 格式：

```
{
  "Status" : "StatusValue",
  "UniqueId" : "Some UniqueId",
  "Data" : "Some Data",
  "Reason" : "Some Reason"
}
```

### Properties
<a name="wait-condition-signal-properties"></a>

`Status` 欄位可以是以下其中一個值：
+ `SUCCESS`
+ `FAILURE`

`UniqueId` 欄位用於識別 CloudFormation 的訊號。如果等待條件的 `Count` 屬性大於 1，`UniqueId` 值在傳送給特定等待條件的所有訊號之間必須是唯一的；否則，CloudFormation 會認為是使用先前傳送過 `UniqueId` 相同之訊號重新傳輸的訊號，而忽略該訊號。

`Data` 欄位可包含您想要隨訊號傳回的任何資訊。在範本內使用 [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) 函數就可存取 `Data` 值。

`Reason` 欄位是字串，內容除了需要符合 JSON 規定以外，沒有其他限制。

## 存取訊號資料
<a name="wait-condition-access-signal-data"></a>

要存取有效訊號傳送的資料，您可在 CloudFormation 範本中建立等待條件的輸出值。例如：

```
Outputs:
  WaitConditionData:
    Description: The data passed back as part of signalling the WaitCondition
    Value: !GetAtt MyWaitCondition.Data
```

然後，您可使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) 命令或 CloudFormation 主控台的**輸出**索引標籤來檢視此資料。

`Fn::GetAtt` 函數會在 JSON 結構內以名稱/值對的形式傳回 `UniqueId` 和 `Data`。例如：

```
{"Signal1":"Application has completed configuration."}
```