

# カスタムリソースを使用してカスタムプロビジョニングロジックを作成する
<a name="template-custom-resources"></a>

カスタムリソースを使用すると、CloudFormation テンプレートにカスタムプロビジョニングロジックを記述し、スタックを作成、更新 (カスタムリソースを変更した場合)、または削除するたびに CloudFormation にそのロジックを実行させることができます。これは、プロビジョニング要件に、CloudFormation の組み込みリソースタイプでは表現できない複雑なロジックやワークフローが含まれる場合に役立ちます。

例えば、CloudFormation のリソースタイプとして使用できないリソースを含める必要があるとします。それらのリソースは、カスタム リソースを使用して含めることができます。この方法により、すべての関連リソースを 1 つのスタックで管理できます。

CloudFormation テンプレートでカスタムリソースを定義するには、`AWS::CloudFormation::CustomResource` または `Custom::MyCustomResourceTypeName` リソースタイプを使用します。カスタムリソースにはサービストークンを示す 1 つのプロパティが必要です。このプロパティは、CloudFormation がリクエストを送信する宛先 (Amazon SNS トピックまたは Lambda 関数など) を指定します。

次のトピックでは、カスタムリソースの使用方法について説明します。

**Topics**
+ [カスタムリソースのしくみ](#how-custom-resources-work)
+ [応答タイムアウト](#response-timeout)
+ [CloudFormation カスタムリソースのリクエストおよびレスポンスのリファレンス](crpg-ref.md)
+ [Amazon SNS を利用するカスタムリソース](template-custom-resources-sns.md)
+ [Lambda を使用するカスタムリソース](template-custom-resources-lambda.md)

**注記**  
CloudFormation レジストリとカスタムリソースには、それぞれ独自の利点があります。カスタムリソースには次の利点があります。  
リソースを登録する必要はありません。
リソース全体を登録せずにテンプレートの一部として含めることができます。
`Create`、`Update`、および `Delete` 操作をサポート
レジストリベースのリソースが提供する利点は次のとおりです。  
サードパーティー製アプリケーションリソースのモデリング、プロビジョニング、および管理をサポート
`Create`、`Read`、`Update`、`Delete`、および `List` (`CRUDL`) 操作をサポート
プライベートおよびサードパーティーのリソースタイプでドリフト検出をサポート
カスタムリソースとは異なり、レジストリベースのリソースは、`CRUDL` 操作を実行するために Amazon SNS トピックや Lambda 関数を関連付ける必要がありません。詳細については、「[CloudFormation レジストリによる拡張機能の管理](registry.md)」を参照してください。

## カスタムリソースのしくみ
<a name="how-custom-resources-work"></a>

新しいカスタムリソースを設定する一般的なプロセスには、次の手順が含まれます。これらの手順には、カスタムリソースを所有する*カスタムリソースプロバイダー*と、カスタムリソースタイプを含むテンプレートを作成する*テンプレート開発者*の 2 つの役割が必要です。これは同じユーザーでもかまいませんが、そうでない場合は、カスタムリソースプロバイダーがテンプレート開発者と連携する必要があります。

1. カスタムリソースプロバイダーは、CloudFormation からのリクエストを処理し、カスタムリソースに対してアクションを実行する方法を決定するロジックを書き込みます。

1. カスタムリソースプロバイダーは、CloudFormation がリクエストを送信できる Amazon SNS トピックまたは Lambda 関数を作成します。Amazon SNS トピックまたは Lambda 関数は、スタックを作成するリージョンと同じリージョンに存在する必要があります。

1. カスタムリソースプロバイダーは、Amazon SNS トピック ARN または Lambda 関数 ARN をテンプレート開発者に提供します。

1. テンプレート開発者は、CloudFormation テンプレートでカスタムリソースを定義します。これには、サービストークンと入力データパラメータが含まれます。サービストークンや入力データの構造は custom resource provider によって定義されます。サービストークンは Amazon SNS トピック ARN または Lambda 関数 ARN を指定し、常に必須ですが、入力データはカスタムリソースに応じてオプションです。

テンプレートを使用してカスタムリソースを作成、更新、削除するたびに、CloudFormation は指定されたサービス トークンにリクエストを送信し、スタック操作を続行する前に、応答を待機します。

テンプレートからスタックを作成するためのフローを以下に示します。

1. CloudFormation は、指定されたサービストークンにリクエストを送信します。このリクエストには、リクエストタイプおよびカスタムリソースが応答を送信する宛先の Amazon S3 バケットの署名付き URL などの情報が含まれています。リクエストに含まれている情報の詳細については、「[CloudFormation カスタムリソースのリクエストおよびレスポンスのリファレンス](crpg-ref.md)」を参照してください。

   以下のサンプルデータは、CloudFormation が `Create` リクエストに含める内容を示しています。　この例では、`ResourceProperties` は CloudFormation が Lambda 関数へ送信するカスタムペイロードの作成を許可します。

   ```
   {
      "RequestType" : "Create",
      "RequestId" : "unique id for this create request",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::TestResource",
      "LogicalResourceId" : "MyTestResource",
      "ResourceProperties" : {
         "Name" : "Value",
         "List" : [ "1", "2", "3" ]
      }
   }
   ```

1. custom resource provider は CloudFormation のリクエストを処理し、`SUCCESS` または `FAILED` の応答を署名付き URL に返します。custom resource provider は、応答を JSON 形式のファイルで提供し、それを署名付き S3 URL にアップロードします。詳細については、「*Amazon Simple Storage Service ユーザーガイド*」の「[署名付き URL を使用したオブジェクトのアップロード](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html)」を参照してください。

   その応答について、custom resource provider には template developer がアクセスできる名前と値のペアも含まれている場合があります。たとえば、応答には要求が成功した場合は出力データ、要求が失敗した場合はエラーメッセージが含まれることがあります。応答の詳細については、「[CloudFormation カスタムリソースのリクエストおよびレスポンスのリファレンス](crpg-ref.md)」を参照してください。
**重要**  
名前と値のペアに機密情報が含まれている場合は、`NoEcho` フィールドを使用して、カスタムリソースの出力をマスクします。それ以外の場合は、プロパティ値 (`DescribeStackEvents` など) を表示する API を通じて値が表示されます。  
`NoEcho` を使用して機密情報をマスクする方法、および動的なパラメータを使用してシークレットを管理する方法の詳細については、「[テンプレートに認証情報を埋め込まない](security-best-practices.md#creds)」ベストプラクティスを参照してください。

   custom resource provider には要求をリッスンして応答する責任があります。例えば、Amazon SNS 通知の場合、custom resource provider は特定のトピック ARN に送信される通知をリッスンして応答する必要があります。CloudFormation は、事前署名済みの URL の場所で応答を待機してリッスンします。

   次のサンプルデータは、カスタムリソースの応答に含まれる可能性がある情報を示します。

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique id for this create request",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MyTestResource",
      "PhysicalResourceId" : "TestResource1",
      "Data" : {
         "OutputName1" : "Value1",
         "OutputName2" : "Value2",
      }
   }
   ```

1. `SUCCESS` 応答を取得した後、CloudFormation はスタックオペレーションを続けます。`FAILED` 応答が返されるか、応答が返されない場合、操作は失敗します。カスタムリソースからの出力データは署名付き URL の場所に保存されます。テンプレートデベロッパーは [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) 関数を使用してそのデータを取得できます。

**注記**  
AWS PrivateLink を使用する場合は、VPC のカスタムリソースには CloudFormation 固有の S3 バケットへのアクセスが必要です。カスタムリソースは、署名付き Amazon S3 URL に応答を送信する必要があります。Amazon S3 に応答を送信できない場合、CloudFormation は応答を受信せず、スタックオペレーションは失敗となります。詳細については、「[インターフェイスエンドポイントを使用した CloudFormation へのアクセス (AWS PrivateLink)](vpc-interface-endpoints.md)」を参照してください。

## 応答タイムアウト
<a name="response-timeout"></a>

カスタムリソースのデフォルトのタイムアウトは 3600 秒 (1 時間) です。この間に応答が受信されない場合、スタック操作は失敗します。

タイムアウト値は、カスタムリソースからの応答にかかると予想される時間に基づいて調整できます。例えば、5 分以内に応答することが予想される Lambda 関数を呼び出すカスタムリソースをプロビジョニングする場合、 `ServiceTimeout` プロパティを指定してスタックテンプレートで 5 分のタイムアウトを設定できます。詳細については、「[CloudFormation カスタムリソースのリクエストおよびレスポンスのリファレンス](crpg-ref.md)」を参照してください。これにより、Lambda 関数にエラーが発生してスタックが停止した場合、CloudFormation は 1 時間待機するのではなく 5 分後にスタック操作を失敗させます。

ただし、タイムアウト値を低く設定しすぎないように注意してください。予期しないタイムアウトを回避するには、カスタムリソースに必要なアクションを実行して応答を返すのに十分な時間があることを確認してください。