Amazon SNS を利用するカスタムリソース - AWS CloudFormation

Amazon SNS を利用するカスタムリソース

次のトピックでは、CloudFormation がリクエストを送信する Amazon SNS トピックを指定するサービストークンを使用してカスタムリソースを設定する方法を示します。また、カスタムリソーススタックの作成、更新、削除の結果として送受信されるイベントとメッセージのシーケンスについても学習します。

カスタムリソースと Amazon SNS を使用すると、新しいリソースのスタックへの追加、スタックへの動的データの挿入などのシナリオが可能になります。例えば、スタックを作成する際に、CloudFormation は、Amazon EC2 インスタンスで実行しているアプリケーションによってモニタリングされるトピックに Create リクエストを送信できます。Amazon SNS 通知は、許可リストされた Elastic IP アドレスのプールの取得など、追加のプロビジョニングタスクを実行するようにアプリケーションをトリガーします。完了すると、アプリケーションは、CloudFormation にスタックオペレーションの続行を通知する応答 (および該当する場合は出力データ) を送信します。

カスタムリソースのターゲットとして Amazon SNS トピックを指定すると、CloudFormation はカスタムリソースに関連するスタックオペレーション中に指定された SNS トピックにメッセージを送信します。これらのメッセージを処理して必要なアクションを実行するには、サポートされているエンドポイントが SNS トピックをサブスクライブするようにする必要があります。

カスタムリソースとその仕組みの概要については、「カスタムリソースを使用してカスタムプロビジョニングロジックを作成する」を参照してください。Amazon SNS とその仕組みの詳細については、「Amazon Simple Notification Service デベロッパーガイド」を参照してください。

Amazon SNS を利用してカスタムリソースを作成する

ステップ 1: スタックの作成

  1. テンプレートデベロッパーは、カスタムリソースを含む CloudFormation スタックを作成します。

    以下のテンプレート例では、論理 ID MySeleniumTest を持つカスタムリソースにカスタムリソースタイプ名 Custom::SeleniumTester を使用します。カスタムリソースタイプの名前は、英数字で 60 文字までの長さにする必要があります。

    カスタムリソースのタイプとともに、custom resource provider によって定義された情報として、サービストークン、オプションのプロバイダー固有のプロパティ、オプションの Fn::GetAtt 属性が宣言されています。これらのプロパティと属性を使用して、template developer から custom resource provider へ、または custom resource provider から template developer へ情報を受け渡しすることができます。サービストークンは、リソースプロバイダーが設定した Amazon SNS トピックを指定します。

    { "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "MySeleniumTest" : { "Type": "Custom::SeleniumTester", "Version" : "1.0", "Properties" : { "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest", "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4" ] } } }, "Outputs" : { "topItem" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] } }, "numRespondents" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] } } } }
    注記

    Fn::GetAtt を使用してアクセスしたデータの名前と値は、プロバイダーから CloudFormation への応答中にカスタムリソースプロバイダーから返されます。custom resource provider がサードパーティーである場合、template developer は、それらの戻り値の名前を custom resource provider から入手する必要があります。

  2. CloudFormation が、スタックに関する情報、スタックテンプレートからのカスタムリソースプロパティ、および応答のための S3 URL が含まれた "RequestType" : "Create" を使用して、リソースプロバイダーに Amazon SNS 通知を送信します。

    通知を送信する際に使用する SNS トピックは、テンプレートの ServiceToken プロパティに埋め込まれます。値をハードコーディングすることを避けるために、テンプレート開発者はテンプレートパラメータを使用します。スタックの起動時に値を入力することができます。

    次の例は、カスタムリソースの Create リクエストを示します。Custom::SeleniumTesterLogicalResourceId として作成されたカスタムリソースタイプの名前 (MySeleniumTester) が含まれています。

    { "RequestType" : "Create", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this create request", "ResourceType" : "Custom::SeleniumTester", "LogicalResourceId" : "MySeleniumTester", "ResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4" ] } }

    Create リクエストのリクエストオブジェクトの詳細については、作成 トピックを参照してください。

  3. custom resource provider は、template developer から送信されたデータを処理し、Create リクエストが成功したかどうかを判断します。リソースプロバイダーは、CloudFormation から送信された S3 URL を使用して、SUCCESS または FAILED の応答を送信します。

    CloudFormation に返される応答フィールドは、応答のタイプによって異なります。特定のリクエストタイプの応答フィールドの詳細については、カスタムリソースのリクエストタイプ セクションのそのリクエストタイプのドキュメントを参照してください。

    custom resource provider は、作成リクエストまたは更新リクエストへの応答として、レスポンスの Data フィールドでデータ要素を返すことができます。これらは名前/値ペアであり、名前は、スタックテンプレートのカスタムリソースで使用されている Fn::GetAtt 属性に対応します。値は、テンプレート開発者が、リソースから属性名を使って Fn::GetAtt を呼び出したときに返されるデータです。

    次に、カスタムリソースのレスポンスの例を示します。

    { "Status" : "SUCCESS", "PhysicalResourceId" : "Tester1", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this create request", "LogicalResourceId" : "MySeleniumTester", "Data" : { "resultsPage" : "http://www.myexampledomain/test-results/guid", "lastUpdate" : "2012-11-14T03:30Z" } }

    Create リクエストの応答オブジェクトの詳細については、作成 トピックを参照してください。

    StackIdRequestId、および LogicalResourceId フィールドはリクエストからそのままコピーする必要があります。

  4. CloudFormation は、スタックのステータスを CREATE_COMPLETE または CREATE_FAILED として宣言します。スタックが正常に作成された場合、template developer は、作成したカスタムリソースの出力値に Fn::GetAtt でアクセスすることで使用できます。

    たとえば、先ほど例示したカスタムリソーステンプレートでは、Fn::GetAtt を使用してリソースの出力をスタック出力にコピーしています。

    "Outputs" : { "topItem" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] } }, "numRespondents" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] } } }

ステップ 2: スタックの更新

既存のスタックを更新するには、以下の例に示すように、スタック内のリソースのプロパティの更新を指定するテンプレートを送信する必要があります。CloudFormation は、テンプレートで指定された変更があるリソースのみを更新します。詳細については、「スタックリソースの更新動作を理解する」を参照してください。

カスタムリソースの更新には、基になる物理リソースの置き換えが伴うことがあります。CloudFormation テンプレートでカスタムリソースを更新すると、CloudFormation が、そのカスタムリソースに更新リクエストを送信します。カスタムリソースを置き換えることが必要になった場合には、新しいカスタムリソースから新しい物理 ID を含むレスポンスを送信する必要があります。CloudFormation は、そのレスポンスを受け取ると、古いカスタムリソースと新しいカスタムリソースの PhysicalResourceId を比較します。この 2 つが異なる場合には、CloudFormation は置き換えが必要な更新と認識し、古いリソースに削除リクエストを送信します (「ステップ 3: スタックの削除」を参照)。

注記

カスタムリソースに変更を行なわない場合、CloudFormation はスタック更新中にリクエストを送信しません。

  1. template developerが、カスタムリソースを含んだスタックの更新を開始します。更新時、template developerは、新しいプロパティをスタックテンプレートで指定できます。

    カスタムリソースタイプを使用したスタックテンプレートに対する Update の例を以下に示します。

    { "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "MySeleniumTest" : { "Type": "Custom::SeleniumTester", "Version" : "1.0", "Properties" : { "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest", "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com", "http://mynewsite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ] } } }, "Outputs" : { "topItem" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] } }, "numRespondents" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] } } } }
  2. CloudFormation が、"RequestType" : "Update" を使用して Amazon SNS 通知をリソースプロバイダーに送信します。これには Create コールに類似する情報が含まれていますが、OldResourceProperties フィールドに古いリソースプロパティが含まれており、ResourceProperties に更新されたリソースプロパティ (存在する場合) が含まれている点が異なります。

    次は、Update リクエストの例です。

    { "RequestType" : "Update", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "uniqueid for this update request", "LogicalResourceId" : "MySeleniumTester", "ResourceType" : "Custom::SeleniumTester", "PhysicalResourceId" : "Tester1", "ResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com", "http://mynewsite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ] }, "OldResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4" ] } }

    Update リクエストのリクエストオブジェクトの詳細については、更新 トピックを参照してください。

  3. CloudFormation から送信されたデータをカスタムリソースプロバイダーが処理します。カスタムリソースは更新を実行し、SUCCESS または FAILED のいずれかの応答を S3 URL に送信します。その後、CloudFormation は古いカスタムリソースと新しいカスタムリソースの PhysicalResourceIDs を比較します。この 2 つが異なる場合には、CloudFormation は置き換えが必要な更新と認識し、古いリソースに削除リクエストを送信します。以下に示したのは、Update リクエストに対するcustom resource providerのレスポンスの例です。

    { "Status" : "SUCCESS", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "uniqueid for this update request", "LogicalResourceId" : "MySeleniumTester", "PhysicalResourceId" : "Tester2" }

    Update リクエストのレスポンスオブジェクトの詳細については、更新「」トピックを参照してください。

    StackIdRequestId、および LogicalResourceId フィールドはリクエストからそのままコピーする必要があります。

  4. CloudFormation は、スタックのステータスを UPDATE_COMPLETE または UPDATE_FAILED として宣言します。更新に失敗すると、スタックはロールバックされます。スタックが正常に更新された場合、template developer は、作成したカスタムリソースの新しい出力値に Fn::GetAtt でアクセスすることができます。

ステップ 3: スタックの削除

  1. テンプレートデベロッパーは、カスタムリソースを含むスタックを削除します。CloudFormation は、スタックテンプレートで指定されている現在のプロパティを SNS トピックとともに取得し、カスタムリソースプロバイダーに対してリクエストを実行する準備をします。

  2. CloudFormation が、スタックに関する現在の情報、スタックテンプレートからのカスタムリソースプロパティ、および応答のための S3 URL が含まれた "RequestType" : "Delete" を使用して、リソースプロバイダーに Amazon SNS 通知を送信します。

    スタックを削除したり、カスタムリソースの削除や置き換えを伴う更新を行ったりした場合は必ず、CloudFormation によって、新旧のカスタムリソース間で PhysicalResourceId が比較されます。この 2 つが異なる場合には、CloudFormation は置き換えが必要な更新と認識し、古いリソース (OldPhysicalResource) の削除リクエストを送信します (以下の Delete リクエストの例を参照)。

    { "RequestType" : "Delete", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this delete request", "ResourceType" : "Custom::SeleniumTester", "LogicalResourceId" : "MySeleniumTester", "PhysicalResourceId" : "Tester1", "ResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com", "http://mynewsite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ] } }

    Delete リクエストのリクエストオブジェクトの詳細については、削除 トピックを参照してください。

    ユーザー定義の名前が指定されている場合、DescribeStackResourceDescribeStackResourcesListStackResources で表示できます。

  3. カスタムリソースプロバイダーは、CloudFormation から送信されたデータを処理し、Delete リクエストが成功したかどうかを判断します。リソースプロバイダーは、CloudFormation から送信された S3 URL を使用して、SUCCESS または FAILED の応答を送信します。カスタムリソースを持つスタックを正常に削除するには、削除リクエストに対して custom resource provider が適切に応答する必要があります。

    以下に示したのは、Delete リクエストに対する custom resource provider のレスポンスの例です。

    { "Status" : "SUCCESS", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this delete request", "LogicalResourceId" : "MySeleniumTester", "PhysicalResourceId" : "Tester1" }

    Delete リクエストのレスポンスオブジェクトの詳細については、削除「」トピックを参照してください。

    StackIdRequestId、および LogicalResourceId フィールドはリクエストからそのままコピーする必要があります。

  4. CloudFormation は、スタックのステータスを DELETE_COMPLETE または DELETE_FAILED として宣言します。