

# CloudFormation テンプレートで待機条件を作成する
<a name="using-cfn-waitcondition"></a>

このトピックでは、テンプレートに待機条件を作成して、スタックリソースの作成を調整したり設定プロセスの進行状況を追跡する方法を説明します。たとえば、アプリケーション構成の一部が完了した後に別のリソースの作成を開始したり、インストールおよび構成プロセス中にシグナルを送信して進行状況を追跡できます。

CloudFormation が待機条件を含むスタックを作成する場合:
+ 他のリソースと同様に待機条件を作成し、待機条件のステータスを `CREATE_IN_PROGRESS` に設定します。
+ CloudFormation は、必要な数の成功シグナルを受信するか、待機条件のタイムアウト期間が経過するまで待機します。
+ タイムアウト期間が経過する前に必要な数の成功シグナルを受信した場合:
  + 待機条件のステータスが `CREATE_COMPLETE` に変わります
  + スタックの作成が続行されます
+ タイムアウト期間が経過するか、障害シグナルを受信した場合:
  + 待機条件のステータスが `CREATE_FAILED` に変わります
  + スタックのロールバック

**重要**  
Amazon EC2 および Auto Scaling リソースについては、待機条件ではなく CreationPolicy 属性を使用することをお勧めします。CreationPolicy 属性をこれらのリソースに追加し、インスタンス作成プロセスが正常に完了したときにシグナルを送信するために cfn-signal ヘルパースクリプトを使用します。  
詳細については、「[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` リソースには、2 つの必須プロパティと 1 つのオプションプロパティがあります。
+ `Handle` (必須) - テンプレートで宣言された `WaitConditionHandle` の参照。
+ `Timeout` (必須) – CloudFormation が、必要な数のシグナルを受信するのを待機する秒数。`Timeout` は最小バインドプロパティです。これは、指定された時刻よりも早くタイムアウトが発生することはありませんが、その後すぐに発生する可能性があることを意味します。指定できる最大時間は 43,200 秒 (12 時間) です。
+ `Count` (オプション) — 待機条件のステータスを `CREATE_COMPLETE` に設定し、スタックの作成を再開する前に CloudFormation が受信する必要がある成功シグナルの数。指定がなければ、デフォルト値は 1 です。

通常、特定のリソースの作成直後に待機条件を開始する必要があります。そのためには、待機条件に `DependsOn` 属性を追加します。待機条件に `DependsOn` 属性を追加すると、CloudFormation は最初に `DependsOn` 属性にリソースを作成し、その後に待機条件を作成します。詳細については、「[DependsOn 属性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-dependson.html)」を参照してください。

次の例は、以下を満たす待機条件を示しています: 
+ `MyEC2Instance` リソースが正常に作成された後に開始される
+ `MyWaitHandle` リソースを `WaitConditionHandle` として使用する
+ タイムアウトは 4,500 秒
+ デフォルト `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 構造である必要があります。

   CloudFormation がスタックの作成を続行するようにするには、`Count` プロパティで指定された数の成功シグナルを送信する必要があります。`Count` が 1 より大きい場合、各シグナルの `UniqueId` 値は、特定の待機条件に送信されるすべてのシグナルにわたって一意である必要があります。`UniqueId` は任意の英数字の文字列です。

   `curl` コマンドは、シグナルを送信する方法の 1 つです。次の例は、待機条件に成功のシグナルを送信する `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"
}
```

### プロパティ
<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."}
```