テンプレートマクロを使用して CloudFormation テンプレートでカスタム処理を実行する - AWS CloudFormation

テンプレートマクロを使用して CloudFormation テンプレートでカスタム処理を実行する

マクロを使用すると、検索して置換操作のような単純なアクションからテンプレート全体の広範な変換まで、テンプレートに対してカスタム処理を実行できるようになります。

幅広い可能性を把握するために、CloudFormation がホストするマクロである AWS::Include および AWS::Serverless トランスフォームを検討してください。

  • AWS::Include 変換 を使用すると、共通テンプレートスニペットをテンプレートに挿入できます。

  • AWS::Serverless 変換 は、AWS Serverless Application Model (AWS SAM) 構文で記述されたテンプレート全体を受け取って、互換性のある CloudFormation テンプレートに変換および拡張します。(サーバーレスアプリケーションおよび AWS SAM の詳細については、「AWS Lambda デベロッパーガイド」の「Deploying Lambda-based applications」(Lambda ベースのアプリケーションのデプロイ) を参照してください。)

CloudFormation マクロの仕組み

マクロを使用してテンプレートを処理するには、2 つの主要なステップがあります。マクロ自体を作成すること、そして次にマクロを使用してテンプレートに対して処理を実行することです。

マクロ定義を作成するには、以下を作成する必要があります。

  • テンプレート処理を実行するための AWS Lambda 関数。この Lambda 関数は、スニペットまたはテンプレート全体、およびユーザーが定義した追加のパラメーターを受け入れます。処理されたテンプレートスニペットまたはテンプレート全体をレスポンスとして返します。

  • AWS::CloudFormation::Macro タイプのリソース。これにより、ユーザーは CloudFormation テンプレート内から Lambda 関数を呼び出すことができます。このリソースは、このマクロを呼び出して Lambda 関数の ARN、およびデバッグを支援するための追加のオプションプロパティを指定します。このリソースをアカウント内に作成するには、AWS::CloudFormation::Macro リソースを記述したテンプレートを作成し、次にそのテンプレートからセルフマネージド型のアクセス許可を持つスタックまたはスタックセットを作成します。AWSCloudFormation StackSets では現在、マクロを参照するテンプレートから、サービスマネージド型アクセス許可を使用してスタックセットを作成または更新することができません。

マクロを使用するには、テンプレート内の次のマクロを参照してください。

  • テンプレートのセクション、つまりスニペットを処理するには、変換したいテンプレートのコンテンツを基準にして配置されている 関数内のマクロを参照します。Fn::Transform を使うときは、必要とされる特定のパラメータを渡すこともできます。

  • テンプレート全体を処理するには、CloudFormation テンプレートの Transform セクション セクションでマクロを参照してください。

次に、通常は変更セットを作成して実行します。(マクロを処理すると、気付かないうちに複数のリソースが追加されていることがあります。マクロに伴うすべての変更を確実に認識できるように、変更セットを使用することを強くお勧めします。) CloudFormation は、マクロリソースに指定された Lambda 関数に、指定されたテンプレートコンテンツとその他の指定されたパラメータを渡します。Lambda 関数は、スニペットまたはテンプレート全体で処理されたテンプレートコンテンツを返します。

テンプレート内のすべてのマクロが呼び出されたら、CloudFormation はテンプレートで処理したコンテンツを含めた変更セットを生成します。変更セットを確認したら、これを実行して変更を適用します。

重要

スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、CAPABILITY_AUTO_EXPAND 機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。

Fn::Transform 組み込み関数またはテンプレートの Transform セクションを使用して、処理されたテンプレートの内容を返すマクロの基盤となる Lambda 関数にテンプレートの内容と関連付けられたパラメータを渡します。
注記

変更セットの提案済みの変更を最初に確認することなく、処理されたテンプレートからスタックを直接作成または更新することに慣れている場合は、CreateStack リクエストまたは UpdateStack リクエストで CAPABILITY_AUTO_EXPAND 機能を指定して作成または更新できます。マクロを参照するテンプレートから直接スタックを作成するのは、どのような処理がマクロで実行されるかを把握している場合に限ります。

詳細については、「AWS CloudFormation API リファレンス」の「CreateStack」または「UpdateStack」を参照してください。

CloudFormation マクロ定義の作成

マクロ定義を作成すると、指定されたアカウントで基盤となる Lambda 関数が使用可能になり、CloudFormation はその関数を呼び出してテンプレートを処理します。

CloudFormation マクロ機能インターフェイス

マクロの場合、CloudFormation は次のイベントマッピングを使用して、基盤となる Lambda 関数を呼び出します。CloudFormation は、JSON 形式でリクエストを送信し、Lambda 関数のレスポンスも JSON 形式で返されると想定しています。

{ "region" : "us-east-1", "accountId" : "$ACCOUNT_ID", "fragment" : { ... }, "transformId" : "$TRANSFORM_ID", "params" : { ... }, "requestId" : "$REQUEST_ID", "templateParameterValues" : { ... } }
  • region

    マクロが存在するリージョン。

  • accountId

    マクロが Lambda 関数を呼び出しているアカウントのアカウント ID。

  • fragment

    カスタム処理に使用可能なテンプレートコンテンツ (JSON 形式)。

    • Transform テンプレートセクションに含まれるマクロの場合は、Transform セクションを除くテンプレート全体になります。

    • Fn::Transform 組み込み関数呼び出しに含まれるマクロでは、Fn::Transform 関数を除く、テンプレート内の組み込み関数の場所に基づくすべての兄弟ノード (およびその子ノード) が含まれます。詳細については、「CloudFormation マクロのスコープ」を参照してください。

  • transformId

    この関数を呼び出すマクロの名前

  • params

    Fn::Transform 関数呼び出しの場合、関数に指定されたパラメータ。CloudFormation は、事前に評価することなく、こうしたパラメータを関数に渡します。

    Transform テンプレートセクションに含まれるマクロの場合、このセクションは空です。

  • requestId

    この関数を呼び出すリクエストの ID です。

  • [templateParameterValues]

    テンプレートの CloudFormation テンプレートの Parameters セクション構文リファレンス セクションに指定されたパラメータ。CloudFormation は、事前に評価してから、こうしたパラメータを関数に渡します。

CloudFormation は、基盤となる関数が次の JSON 形式でレスポンスを返すと想定しています。

{ "requestId" : "$REQUEST_ID", "status" : "$STATUS", "fragment" : { ... } "errorMessage": "optional error message for failures" }
  • requestId

    この関数を呼び出すリクエストの ID です。関数を呼び出すときに CloudFormation から提供されたリクエスト ID と一致する必要があります。

  • status

    リクエストのステータスです (大文字小文字を区別しません)。success のように設定する必要があります。CloudFormation は、他のすべてのレスポンスを失敗として扱います。

  • fragment

    処理済みのテンプレートに含められる、CloudFormation が処理したテンプレートコンテンツ (兄弟など)。CloudFormation は、Lambda 関数に渡されるテンプレートコンテンツを Lambda レスポンスで受け取るテンプレートフラグメントに置き換えます。

    処理されたテンプレートのコンテンツは有効な JSON であり、処理されたテンプレートに含まれると有効なテンプレートになる必要があります。

    関数が実際に CloudFormation から渡されるテンプレートコンテンツを変更しないものの、処理済みのテンプレートにそのコンテンツを含める必要がある場合、関数はレスポンスとしてそのテンプレートコンテンツを CloudFormation に返す必要があります。

  • errorMessage

    変換が失敗した理由を説明するエラーメッセージ。CloudFormation は、スタックの [Stack details] (スタックの詳細) ページの [Events] (イベント) ペインに、このエラーメッセージを表示します。

    例えば、「変更セットの作成エラー: AWS アカウント アカウント番号::マクロ名の変換に失敗しました: エラーメッセージ文字列」。

マクロを作成する際の追加の考慮事項については、「CloudFormation マクロ定義を作成する際の考慮事項」を参照してください。

CloudFormation マクロアカウントのスコープとアクセス許可

マクロは、リソースとして作成されたアカウントでのみ使用できます。マクロ名は指定のアカウント内で一意である必要があります。ただし、基盤となる Lambda 関数でクロスアカウントアクセスを有効にし、その後複数のアカウントでその機能を参照するマクロ定義を作成することで、同じ機能を複数のアカウントで使用できるようにすることができます。以下の例では、3 つのアカウントにそれぞれ同じ Lambda 関数を指すマクロ定義が含まれています。

Lambda 関数でクロスアカウントアクセスを許可することで、AWS はその関数を参照するマクロを複数のアカウントで作成することを可能にします。

詳細については、「AWS Lambda デベロッパーガイド」の「AWS Lambda リソースへの許可の管理の概要」を参照してください。

マクロ定義を作成するには、ユーザーは指定されたアカウント内にスタックまたはスタックセットを作成するための許可を持っていなければなりません。

CloudFormation がテンプレートに含まれているマクロを正常に実行するには、ユーザーは基盤となる Lambda 関数に対する Invoke アクセス権限を持っている必要があります。アクセス権限がエスカレーションしないよう、マクロの実行中に CloudFormation はユーザーとして振る舞います。詳細については、「AWS Lambda デベロッパーガイド」の「Lambda 許可モデル」および「IAM ユーザーガイド」の「AWS Lambda のアクションと条件コンテキストキー」を参照してください。

AWS::Serverless 変換 および AWS::Include 変換 トランスフォームは、CloudFormation がホストするマクロです。その使用に特別なアクセス権限は必要なく、CloudFormation の任意のアカウント内から使用できます。

CloudFormation マクロのデバッグ

デバッグを支援するために、マクロの AWS::CloudFormation::Macro リソースタイプを作成する際に LogGroupName プロパティと LogRoleArn プロパティを指定することもできます。これらのプロパティを使用すると、マクロの基盤となる AWS Lambda 関数を呼び出すときに CloudFormation がエラーログ情報を送信する CloudWatch ロググループを指定でき、またそれらのログにログエントリを送信するときに CloudFormation が引き受けるロールを指定できます。

「請求」

マクロが実行されると、その関数の実行に関連する料金が Lambda 関数の所有者に請求されます。

AWS::Serverless 変換 および AWS::Include 変換 トランスフォームは、CloudFormation がホストするマクロです。これらの使用料は発生しません。

CloudFormation マクロ定義を作成する際の考慮事項

マクロ定義を作成するときは、次の点に留意してください。

  • マクロは AWS Lambda を使用できる AWS リージョン だけでサポートされます。Lambda を使用できるリージョンのリストについては、「AWS Lambda endpoints and quotas」( エンドポイントとクォータ) を参照してください。

  • 処理されたテンプレートスニペットはすべて有効な JSON である必要があります。

  • 処理されたテンプレートのスニペットは、スタックの作成、スタックの更新、スタックセットの作成、またはスタックセットの更新オペレーションの検証チェックに合格する必要があります。

  • CloudFormation は、まずマクロを解決し、次にテンプレートを処理します。生成されるテンプレートは有効な JSON である必要があり、テンプレートサイズ制限を超えることはできません。

  • CloudFormation がテンプレート内のエレメントを処理する順序のため、マクロは CloudFormation に返される処理済みテンプレートコンテンツにモジュールを含めることはできません。モジュールの詳細については、「CloudFormation CLI ユーザーガイド」の「Developing modules」(モジュールの開発) を参照してください。

  • 更新ロールバック機能を使用する場合、CloudFormation は元のテンプレートのコピーを使用します。含まれるスニペットが変更されていても、元のテンプレートにロールバックされます。

  • マクロは再帰的に処理されないため、マクロをマクロ内に含めることはできません。

  • Fn::ImportValue 組み込み関数は、現在マクロではサポートされていません。

  • テンプレートに含まれている組み込み関数は、マクロの後で評価されます。したがって、マクロが返す処理済みテンプレートコンテンツに組み込み関数の呼び出しを含めることができ、それらは通常どおりに評価されます。

  • StackSets では現在、マクロを参照するテンプレートから、サービスマネージド型アクセス許可を使用してスタックセットを作成または更新することができません。

  • スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成または更新する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、CAPABILITY_AUTO_EXPAND 機能を指定します。マクロを処理すると、知らないうちに複数のリソースが追加される可能性があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。

  • 現在、変更セットはネストされたスタックをサポートしていません。マクロを参照し、ネストされたスタックが含まれているスタックテンプレートを使用してスタックを作成または更新する場合は、スタックを直接作成または更新する必要があります。これを実行するには、CreateStack アクションまたは UpdateStack アクションを使用して CAPABILITY_AUTO_EXPAND 機能を指定します。

CloudFormation マクロ定義を作成するには:
  1. CloudFormation テンプレートを処理するAWS Lambda 関数を構築します

    作成した Lambda 関数はテンプレートの内容の処理を実行します。関数は、テンプレート全体までの、テンプレートの任意の部分を処理することができます。関数が準拠する必要があるイベントマッピングについては、「CloudFormation マクロ機能インターフェイス」を参照してください。マクロを作成する際の追加の考慮事項については、「CloudFormation マクロ定義を作成する際の考慮事項」を参照してください。

  2. AWS::CloudFormation::Macro リソースタイプを記述したテンプレートを作成します

    • Name プロパティと FunctionName プロパティを指定する必要があります。FunctionName プロパティでは、CloudFormation がマクロを実行するときに呼び出す Lambda 関数の ARN を指定します。

    • デバッグを支援するために、LogGroupName および LogRoleArn プロパティも指定できます。

  3. 目的のアカウントのマクロを含むテンプレートからスタックを作成するか、管理者アカウントのマクロを参照するテンプレートからセルフマネージド型のアクセス許可を持つスタックセットを作成することで、目的のターゲットアカウントにスタックインスタンスを作成します。

    CloudFormation がマクロ定義を含むスタックを正常に作成したら、そのアカウント内でマクロを使用できるようになります。

テンプレートで CloudFormation マクロを使用する

CloudFormation がマクロ定義を含むスタックを正常に作成したら、そのアカウント内でマクロを使用できるようになります。処理するテンプレートの内容に関連する適切な場所で、テンプレート内でマクロを参照して使用します。

CloudFormation マクロの評価順序

テンプレートによっては、CloudFormation がホストするトランスフォーム (AWS::Include 変換AWS::Serverless 変換 など) をはじめ複数のマクロを参照できます。

マクロは、テンプレート内の位置に基づいて、最も深く外側にネストされているものから最も一般的なものまで順番に評価されます。テンプレート内の同じ場所にあるマクロは、リストされている順序に基づいて順番に評価されます。

AWS::IncludeAWS::Transform などの変換は、アクションの順序と範囲の点で他のマクロと同じように扱われます。

例えば、以下のテンプレートサンプルでは、PolicyAdder マクロが最初に評価されます。テンプレート内で最も深くネストされているからです。次に、AWS::Serverless よりも先に MyMacro が評価されます。Transform セクションで AWS::Serverless より前に記述されているからです。

AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro, AWS::Serverless] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' Properties: BucketName: amzn-s3-demo-bucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: PolicyAdder CorsConfiguration: [] MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: ami-1234567890abcdef0

CloudFormation マクロのスコープ

テンプレートの Transform セクションで参照されているマクロは、そのテンプレートの内容全体を処理できます。

Fn::Transform 関数で参照されているマクロは、テンプレート内のその Fn::Transform 関数の兄弟要素 (子を含む) の内容を処理できます。

たとえば、以下のテンプレートサンプルでは、AWS::Include は、それ自身を含む Fn::Transform 関数の場所に基づいて、MyBucket プロパティを処理できます。MyMacro は、Transform セクションに含まれているため、テンプレート全体の内容を処理できます。

# Start of processable content for MyMacro AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' # Start of processable content for AWS::Include Properties: BucketName: amzn-s3-demo-bucket1 Tags: [{"key":"value"}] 'Fn::Transform': - Name: 'AWS::Include' Parameters: Location: s3://amzn-s3-demo-bucket2/MyFileName.yaml CorsConfiguration: [] # End of processable content for AWS::Include MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: ami-1234567890abcdef0 # End of processable content for MyMacro

変更セットおよび CloudFormation マクロ

マクロを参照するテンプレートを使用してスタックを作成または更新するには、通常、変更セットを作成して実行します。変更セットは、処理されたテンプレートに基づいて CloudFormation が実行するアクションを記述します。マクロを処理すると、知らないうちに複数のリソースが追加される可能性があります。マクロに伴うすべての変更を確実に認識できるように、変更セットを使用することを強くお勧めします。変更セットを確認したら、これを実行して実際に変更を適用します。

マクロによってテンプレートに IAM リソースが追加されることがあります。これらのリソースの場合、それぞれどのような機能を備えているかを確認する必要があります。CloudFormation は、テンプレートを処理しなければ、どのリソースが追加されるのかを認識することができません。そのため、参照されたマクロに IAM リソースが含まれている場合は、IAM の機能を把握したうえで変更セットを作成する必要があります。こうすることで、変更セットを実行するときに、CloudFormation が IAM リソースを作成するために必要な機能を準備できます。

重要

スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、CAPABILITY_AUTO_EXPAND 機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。

注記

変更セットの提案済みの変更を最初に確認することなく、処理されたテンプレートからスタックを直接作成または更新することに慣れている場合は、CreateStack リクエストまたは UpdateStack リクエストで CAPABILITY_AUTO_EXPAND 機能を指定して作成または更新できます。マクロが含まれているスタックテンプレートから直接スタックを作成するのは、どのような処理がマクロで実行されるかを把握している場合に限ります。スタックセットマクロで変更セットを使用することはできません。スタックセットを直接更新してください。

詳細については、「AWS CloudFormation API リファレンス」の「CreateStack」または「UpdateStack」を参照してください。

AWS CLI を使用する場合は、package および deploy コマンドを使用して、マクロを参照するテンプレートからスタックを起動する際のステップ数を減らすことができます。詳細については、「AWS Lambda デベロッパーガイド」の「Deploying Lambda-based applications」(Lambda ベースのアプリケーションのデプロイ) を参照してください。

テンプレートのステージと CloudFormation のマクロ

テンプレートのステージは、そのテンプレートがユーザーによって送信されたオリジナルのテンプレートか、CloudFormation によってマクロを処理されたものかを示します。

  • Original: ユーザーがスタックまたはスタックセットを作成または更新するために最初に送信したテンプレートです。

  • Processed: 参照されたマクロを処理した後にスタックまたはスタックセットを作成または更新するために CloudFormation が使用したテンプレートです。元のテンプレートが YAML としてフォーマットされていても、処理されたテンプレートは JSON としてフォーマットされます。

スタックの問題のトラブルシューティングには、処理済みテンプレートを使用します。テンプレートがマクロを参照していない場合は、オリジナルと処理済みのテンプレートは同一です。

CloudFormation コンソールまたは AWS CLI を使用して、スタックテンプレートのステージを確認できます。

注記

処理されたスタックテンプレートの最大サイズは、CreateStackUpdateStack、または ValidateTemplate リクエスト内に直接渡す場合は 51,200 バイトです。Amazon S3 テンプレート URL を使用して S3 オブジェクトとして渡す場合は 1 MB です。ただし、CloudFormation はテンプレート内のマクロを連続的に処理するため、処理中にテンプレートの一時的な状態が更新されます。このため、処理中のテンプレートのサイズは、完全に処理されたテンプレートの許容サイズを一時的に超える場合があります。CloudFormation は、これらのインプロセステンプレートにいくらかのバッファを許可します。ただし、テンプレートやマクロを設計する際は、処理済みのスタックテンプレートの最大許容サイズに留意してください。

テンプレートの処理中に CloudFormation から Transformation data limit exceeded エラーが返された場合は、CloudFormation で処理中に許容される最大テンプレートサイズを超えています。

この問題を解決するには、以下の対処を検討してください。

  • テンプレートを複数のテンプレートに再構成し、処理中のテンプレートが最大サイズを超えないようにします。例:

  • 特定のマクロから返されるテンプレートフラグメントのサイズを小さくします。CloudFormation はマクロから返されるフラグメントの内容には干渉しません。

テンプレートで CloudFormation マクロを使用するには
注記

CloudFormation がテンプレートで参照されているマクロを正常に実行するには、ユーザーが基盤となる Lambda 関数に対して Invoke アクセス権限を持っている必要があります。詳細については、「AWS Lambda デベロッパーガイド」の「AWS Lambda リソースへの許可の管理の概要」を参照してください。

  1. テンプレートにマクロへの参照を含めます。

    • テンプレートのスニペットを処理するには、処理したいテンプレートのコンテンツを基準にして配置されている Fn::Transform 関数内のマクロを参照します。

    • テンプレート全体を処理するには、CloudFormation テンプレートの Transform セクション セクションでマクロを参照してください。

  2. テンプレートを使用して変更セットを作成します。

    重要

    スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、CAPABILITY_AUTO_EXPAND 機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。

  3. 変更セットの確認および変更セットの実行をします。

    重要

    スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、CAPABILITY_AUTO_EXPAND 機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。

マクロの例

このガイドの マクロの例: マクロの作成と使用 チュートリアルに加えて、ソースコードやテンプレートを含むサンプルマクロが GitHub リポジトリにあります。これらの例は、説明を目的として「現状のまま」提供されています。

以下も参照してください。

AWS::CloudFormation::Macro

CloudFormation テンプレートの Transform セクション

Fn::Transform

AWS::Serverless 変換

AWS::Include 変換