AWS CloudFormation マクロを使用したテンプレートのカスタム処理の実行
マクロを使用すると、検索して置換操作のような単純なアクションからテンプレート全体の広範な変換まで、テンプレートに対してカスタム処理を実行できるようになります。
幅広い可能性を把握するには AWS CloudFormation によってホストされるマクロである AWS::Include
および AWS::Serverless
トランスフォームを検討してください。
-
AWS::Include 変換
を使用すると、共通テンプレートスニペットをテンプレートに挿入できます。 -
AWS::Serverless 変換
は、AWS Serverless Application Model (AWS SAM) 構文で記述されたテンプレート全体を受け取り、準拠する AWS CloudFormation テンプレートに変換および拡張します。(サーバーレスアプリケーションおよび AWS SAM の詳細については、「AWS Lambda デベロッパーガイド」の「Deploying Lambda-based applications」(Lambda ベースのアプリケーションのデプロイ) を参照してください。)
AWS CloudFormation マクロの仕組み
マクロを使用してテンプレートを処理するには、2 つの主要なステップがあります。マクロ自体を作成すること、そして次にマクロを使用してテンプレートに対して処理を実行することです。
マクロ定義を作成するには、以下を作成する必要があります。
-
テンプレート処理を実行するための AWS Lambda 関数。この Lambda 関数は、スニペットまたはテンプレート全体、およびユーザーが定義した追加のパラメーターを受け入れます。処理されたテンプレートスニペットまたはテンプレート全体をレスポンスとして返します。
-
AWS::CloudFormation::Macro
タイプのリソース。これにより、ユーザーは AWS CloudFormation テンプレート内から Lambda 関数を呼び出すことができます。このリソースは、このマクロを呼び出して Lambda 関数の ARN、およびデバッグを支援するための追加のオプションプロパティを指定します。このリソースをアカウント内に作成するには、AWS::CloudFormation::Macro
リソースを含むテンプレートを作成し、次にテンプレートからセルフマネージド型のアクセス許可を持つスタックまたはスタックセットを作成します。AWSCloudFormation StackSets では現在、マクロを参照するテンプレートから、サービスマネージド型アクセス許可を使用してスタックセットを作成または更新することができません。
マクロを使用するには、テンプレート内の次のマクロを参照してください。
-
テンプレートのセクション、つまりスニペットを処理するには、変換したいテンプレートのコンテンツを基準にして配置されている
Fn::Transform
関数内のマクロを参照します。Fn::Transform
を使うときは、必要とされる特定のパラメータを渡すこともできます。 -
テンプレート全体を処理するには、変換 セクションでマクロを参照してください。
次に、通常は変更セットを作成して実行します。(マクロを処理すると、気付かないうちに複数のリソースが追加されていることがあります。マクロに伴うすべての変更を確実に認識できるように、変更セットを使用することを強くお勧めします。) AWS CloudFormation は、マクロリソースで指定された Lambda 関数に、指定されたテンプレートのコンテンツとその他の指定されたパラメータを渡します。Lambda 関数は、スニペットまたはテンプレート全体で処理されたテンプレートコンテンツを返します。
テンプレート内のすべてのマクロが呼び出された後、AWS CloudFormation は処理されたテンプレートコンテンツを含む変更セットを生成します。変更セットを確認したら、これを実行して変更を適用します。
重要
スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet
または UpdateStackSet
操作を使用して、CAPABILITY_AUTO_EXPAND
機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。
注記
変更セットの提案済みの変更を最初に確認することなく、処理されたテンプレートからスタックを直接作成または更新することに慣れている場合は、CreateStack
リクエストまたは UpdateStack
リクエストで CAPABILITY_AUTO_EXPAND
機能を指定して作成または更新できます。マクロを参照するテンプレートから直接スタックを作成するのは、どのような処理がマクロで実行されるかを把握している場合に限ります。
詳細については、「AWS CloudFormation API リファレンス」の「CreateStack」または「UpdateStack」を参照してください。
AWS CloudFormation マクロ定義の作成
マクロ定義を作成すると、そのマクロ定義によって、指定されたアカウントで基盤となる Lambda 関数が使用可能になるため、AWS CloudFormation はそれを呼び出してテンプレートを処理できます。
AWS CloudFormation マクロ機能インターフェース
マクロの場合、AWS CloudFormation は以下のイベントマッピングを使用して基盤となる Lambda 関数を呼び出します。AWS CloudFormation はリクエストを JSON 形式で送信し、関数のレスポンスも 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
関数を除く、テンプレート内の組み込み関数の場所に基づくすべての兄弟ノード (およびその子ノード) が含まれます。詳細については、「AWS CloudFormation マクロスコープ」を参照してください。
-
-
transformId
この関数を呼び出すマクロの名前
-
params
Fn::Transform
関数呼び出しの場合に、関数に指定されているパラメータです。AWS CloudFormation は、これらのパラメータを関数に渡す前には評価をしません。Transform
テンプレートセクションに含まれるマクロの場合、このセクションは空です。 -
requestId
この関数を呼び出すリクエストの ID です。
-
[templateParameterValues]
テンプレートの パラメータ セクションに指定されているすべてのパラメータです。AWS CloudFormation はこれらのパラメータを関数に渡す前に評価します。
AWS CloudFormation は、基盤となる関数が次の JSON 形式でレスポンスを返すことを意図しています。
{ "requestId" : "
$REQUEST_ID
", "status" : "$STATUS
", "fragment" : {...
} "errorMessage": "optional error message for failures" }
-
requestId
この関数を呼び出すリクエストの ID です。関数を呼び出すときに AWS CloudFormation によって提供されたリクエスト ID と一致する必要があります。
-
status
リクエストのステータスです (大文字小文字を区別しません)。
success
に設定する必要があります。AWS CloudFormation は他のすべてのレスポンスを失敗として扱います。 -
fragment
兄弟を含む処理済みテンプレートに含める AWS CloudFormation の処理済みテンプレートコンテンツです。AWS CloudFormation は、Lambda 関数に渡されたテンプレートコンテンツを、Lambda レスポンスで受け取ったテンプレートフラグメントで置き換えます。
処理されたテンプレートのコンテンツは有効な JSON であり、処理されたテンプレートに含まれると有効なテンプレートになる必要があります。
関数が実際に AWS CloudFormation から渡されるテンプレートコンテンツを変更しないものの、処理済みのテンプレートにそのコンテンツを含める必要がある場合、関数は応答としてそのテンプレートコンテンツを AWS CloudFormation に返す必要があります。
-
errorMessage
変換が失敗した理由を説明するエラーメッセージ。CloudFormation は、スタックの [Stack details] (スタックの詳細) ページの [Events] (イベント) ペインに、このエラーメッセージを表示します。
例えば、「変更セットの作成エラー:
AWS アカウント アカウント番号
::マクロ名
の変換に失敗しました:エラーメッセージ文字列
」。
マクロを作成する際の追加の考慮事項については、「AWS CloudFormation マクロ定義を作成する際の考慮事項」を参照してください。
AWS CloudFormation マクロアカウントの範囲とアクセス許可
マクロは、リソースとして作成されたアカウントでのみ使用できます。マクロ名は指定のアカウント内で一意である必要があります。ただし、基盤となる Lambda 関数でクロスアカウントアクセスを有効にし、その後複数のアカウントでその機能を参照するマクロ定義を作成することで、同じ機能を複数のアカウントで使用できるようにすることができます。以下の例では、3 つのアカウントにそれぞれ同じ Lambda 関数を指すマクロ定義が含まれています。
詳細については、「AWS Lambda デベロッパーガイド」の「AWS Lambda リソースへの許可の管理の概要」を参照してください。
マクロ定義を作成するには、ユーザーは指定されたアカウント内にスタックまたはスタックセットを作成するための許可を持っていなければなりません。
AWS CloudFormation がテンプレートに含まれているマクロを正常に実行するには、ユーザーは基盤となる Lambda 関数に対する Invoke
アクセス許可を持っている必要があります。アクセス権限がエスカレーションしないよう、マクロの実行中に AWS CloudFormation はユーザーとして振る舞います。詳細については、「AWS Lambda デベロッパーガイド」の「Lambda 許可モデル」および「IAM ユーザーガイド」の「AWS Lambda のアクションと条件コンテキストキー」を参照してください。
AWS::Serverless 変換 および AWS::Include 変換 トランスフォームは、AWS CloudFormation によってホストされるマクロです。それらを使用するために特別なアクセス権限は必要ではなく、AWS CloudFormation の任意のアカウント内から使用できます。
AWS CloudFormation マクロのデバッグ
デバッグをサポートするために、マクロの AWS::CloudFormation::Macro リソースタイプを作成する際に、LogGroupName
プロパティと LogRoleArn
プロパティを指定できます。これらのプロパティを使用すると、マクロの基盤となる AWS Lambda 関数を呼び出すときに AWS CloudFormation がエラーログ情報を送信する CloudWatch ロググループ、およびそれらのログにログエントリを送信するときに AWS CloudFormation が引き受けるロールを指定できます。
「請求」
マクロが実行されると、その関数の実行に関連する料金が Lambda 関数の所有者に請求されます。
AWS::Serverless 変換 および AWS::Include 変換 トランスフォームは、AWS CloudFormation によってホストされるマクロです。これらの使用料は発生しません。
AWS CloudFormation マクロ定義を作成する際の考慮事項
マクロ定義を作成するときは、次の点に留意してください。
-
マクロは AWS Lambda を使用できる AWS リージョン だけでサポートされます。Lambda を使用できるリージョンのリストについては、「AWS Lambda endpoints and quotas」( エンドポイントとクォータ) を参照してください。
-
処理されたテンプレートスニペットはすべて有効な JSON である必要があります。
-
処理されたテンプレートのスニペットは、スタックの作成、スタックの更新、スタックセットの作成、またはスタックセットの更新オペレーションの検証チェックに合格する必要があります。
-
AWS CloudFormation は最初にマクロを解決し、次いでテンプレートを処理します。生成されるテンプレートは有効な JSON である必要があり、テンプレートサイズ制限を超えることはできません。
-
CloudFormation がテンプレート内のエレメントを処理する順序のため、マクロは CloudFormation に返される処理済みテンプレートコンテンツにモジュールを含めることはできません。モジュールの詳細については、「CloudFormation CLI ユーザーガイド」の「Developing modules」(モジュールの開発) を参照してください。
-
更新ロールバック機能を使用する場合、AWS CloudFormation は元のテンプレートのコピーを使用します。含まれるスニペットが変更されていても、元のテンプレートにロールバックされます。
-
マクロを繰り返し処理しないため、マクロをマクロに含めることはできません。
-
Fn::ImportValue
組み込み関数は、現在マクロではサポートされていません。 -
テンプレートに含まれている組み込み関数は、マクロの後で評価されます。したがって、マクロが返す処理済みテンプレートコンテンツに組み込み関数の呼び出しを含めることができ、それらは通常どおりに評価されます。
-
StackSets では現在、AWS CloudFormation マクロを参照するテンプレートから、サービスマネージド型アクセス許可を使用してスタックセットを作成または更新することができません。
-
スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成または更新する必要があります。スタックセットを直接作成または更新するには、
CreateStackSet
またはUpdateStackSet
操作を使用して、CAPABILITY_AUTO_EXPAND
機能を指定します。マクロを処理すると、知らないうちに複数のリソースが追加される可能性があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。 -
現在、変更セットはネストされたスタックをサポートしていません。マクロを参照し、ネストされたスタックが含まれているスタックテンプレートを使用してスタックを作成または更新する場合は、スタックを直接作成または更新する必要があります。これを実行するには、
CreateStack
またはUpdateStack
アクションを使用してCAPABILITY_AUTO_EXPAND
機能を指定します。
AWS CloudFormation マクロ定義を作成するには
-
AWS CloudFormation テンプレートを処理するAWS Lambda 関数を構築します。
作成した Lambda 関数はテンプレートの内容の処理を実行します。関数は、テンプレート全体までの、テンプレートの任意の部分を処理することができます。関数が準拠する必要があるイベントマッピングについては、「AWS CloudFormation マクロ機能インターフェース」を参照してください。マクロを作成する際の追加の考慮事項については、「AWS CloudFormation マクロ定義を作成する際の考慮事項」を参照してください。
-
AWS::CloudFormation::Macro リソースタイプを含むテンプレートを作成します。
-
Name
プロパティとFunctionName
プロパティを指定する必要があります。FunctionName
プロパティは、AWS CloudFormation がマクロを実行するときに呼び出す Lambda 関数の ARN を指定します。 -
デバッグを支援するために、
LogGroupName
およびLogRoleArn
プロパティも指定できます。
-
-
目的のアカウントのマクロを含むテンプレートからスタックを作成するか、管理者アカウントのマクロを参照するテンプレートからセルフマネージド型のアクセス許可を持つスタックセットを作成することで、目的のターゲットアカウントにスタックインスタンスを作成します。
AWS CloudFormation がマクロ定義を含むスタックの作成に成功すると、そのアカウント内でマクロを使用できるようになります。
テンプレートで AWS CloudFormation マクロを使用する
AWS CloudFormation がマクロ定義を含むスタックの作成に成功すると、そのアカウント内でマクロを使用できるようになります。処理するテンプレートの内容に関連する適切な場所で、テンプレート内でマクロを参照して使用します。
AWS CloudFormation マクロ評価順
AWS::Include 変換 や AWS::Serverless 変換 など、AWS CloudFormation によってホストされているトランスフォームを含む、特定のテンプレート内の複数のマクロを参照できます。
マクロは、テンプレート内の位置に基づいて、最も深く外側にネストされているものから最も一般的なものまで順番に評価されます。テンプレート内の同じ場所にあるマクロは、リストされている順序に基づいて順番に評価されます。
AWS::Include
や AWS::Transform
などの変換は、アクションの順序と範囲の点で他のマクロと同じように扱われます。
例えば、以下のテンプレートサンプルでは、テンプレートで最も深くネストされているマクロなので、AWS CloudFormation が PolicyAdder
マクロを最初に評価します。Transform
セクションで AWS::Serverless
より前にリストされているため、AWS CloudFormation は AWS::Serverless
を評価する前に MyMacro
を評価します。
AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro, AWS::Serverless] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' Properties: BucketName: MyBucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: PolicyAdder CorsConfiguration:[] MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: "ami-123"
AWS 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: MyBucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: 'AWS::Include' Parameters: Location: s3://DOC-EXAMPLE-BUCKET/MyFileName.yaml CorsConfiguration:[] //End of processable content for AWS::Include MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: "ami-123" // End of processable content for MyMacro
変更セットおよび AWS CloudFormation マクロ
マクロを参照するテンプレートを使用してスタックを作成または更新するには、通常、変更セットを作成して実行します。変更セットは、処理されたテンプレートに基づいて CloudFormation が実行するアクションを記述します。マクロを処理すると、知らないうちに複数のリソースが追加される可能性があります。マクロに伴うすべての変更を確実に認識できるように、変更セットを使用することを強くお勧めします。変更セットを確認したら、これを実行して実際に変更を適用します。
マクロによってテンプレートに IAM リソースが追加されることがあります。これらのリソースについて、AWS CloudFormation ではその機能を確認する必要があります。AWS CloudFormation では、どのリソースが追加されるかをテンプレートの処理前に認識することはできないため、参照されたマクロに IAM リソースが含まれているかどうかによって、変更セットを作成するときにユーザーが IAM の機能を把握しておく必要がある場合があります。こうすることで、変更セットを実行するときに、AWS 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 のマクロ
テンプレートのステージは、そのテンプレートがユーザーによって送信されたオリジナルのテンプレートか、AWS CloudFormation によってマクロを処理されたものかを示します。
-
Original
: ユーザーがスタックまたはスタックセットを作成または更新するために最初に送信したテンプレートです。 -
Processed
: 参照されたマクロを処理した後にスタックまたはスタックセットを作成または更新するために使用されたテンプレート AWS CloudFormation です。元のテンプレートが YAML としてフォーマットされていても、処理されたテンプレートは JSON としてフォーマットされます。
スタックの問題のトラブルシューティングには、処理済みテンプレートを使用します。テンプレートがマクロを参照していない場合は、オリジナルと処理済みのテンプレートは同一です。
AWS CloudFormation コンソールまたは AWS CLI を使用して、スタックのテンプレートのステージを確認できます。
注記
処理されたスタックテンプレートの最大サイズは、CreateStack
、UpdateStack
、または ValidateTemplate
リクエスト内に直接渡す場合は 51,200 バイトです。Amazon S3 テンプレート URL を使用して S3 オブジェクトとして渡す場合は 1 MB です。ただし、CloudFormation はテンプレート内のマクロを連続的に処理するため、処理中にテンプレートの一時的な状態が更新されます。このため、処理中のテンプレートのサイズは、完全に処理されたテンプレートの許容サイズを一時的に超える場合があります。CloudFormation は、これらのインプロセステンプレートにいくらかのバッファを許可します。ただし、テンプレートやマクロを設計する際は、処理済みのスタックテンプレートの最大許容サイズに留意してください。
テンプレートの処理中に CloudFormation から Transformation data limit exceeded
エラーが返された場合は、CloudFormation で処理中に許容される最大テンプレートサイズを超えています。
この問題を解決するには、以下の対処を検討してください。
-
テンプレートを複数のテンプレートに再構成し、処理中のテンプレートが最大サイズを超えないようにします。例:
-
ネストされたスタックテンプレートを使用して、テンプレートの各パートをカプセル化します。詳細については、「ネストされたスタックの操作」を参照してください。
-
複数のスタックを作成し、クロススタック参照を使用してスタック間で情報を交換します。詳細については、「チュートリアル: 別の AWS CloudFormation スタックのリソース出力を参照する」を参照してください。
-
-
特定のマクロから返されるテンプレートフラグメントのサイズを小さくします。CloudFormation はマクロから返されるフラグメントの内容には干渉しません。
テンプレートで AWS CloudFormation マクロを使用するには
注記
AWS CloudFormation がテンプレートで参照されているマクロを正常に実行するには、ユーザーは基盤となる Lambda 関数に対する Invoke
アクセス許可を持っている必要があります。詳細については、「AWS Lambda デベロッパーガイド」の「AWS Lambda リソースへの許可の管理の概要」を参照してください。
-
テンプレートにマクロへの参照を含めます。
-
テンプレートのスニペットを処理するには、処理したいテンプレートのコンテンツを基準にして配置されている
Fn::Transform
関数内のマクロを参照します。 -
テンプレート全体を処理するには、変換 セクションでマクロを参照してください。
-
-
テンプレートを使用して変更セットを作成します。
重要
スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、
CreateStackSet
またはUpdateStackSet
操作を使用して、CAPABILITY_AUTO_EXPAND
機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。 -
変更セットの確認および変更セットの実行をします。
重要
スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、
CreateStackSet
またはUpdateStackSet
操作を使用して、CAPABILITY_AUTO_EXPAND
機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。
マクロの例
このガイドの「」のチュートリアルに加えて、GitHub の「Amazon Web Service - ラボ」の「マクロの例」セクションに、ソースコードとテンプレートを含むサンプルマクロの例があります。これらの例は、説明を目的として「現状のまま」提供されています。