テンプレートマクロを使用して 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
機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。
注記
変更セットの提案済みの変更を最初に確認することなく、処理されたテンプレートからスタックを直接作成または更新することに慣れている場合は、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 関数を指すマクロ定義が含まれています。
詳細については、「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 マクロ定義を作成するには:
-
CloudFormation テンプレートを処理するAWS Lambda 関数を構築します。
作成した Lambda 関数はテンプレートの内容の処理を実行します。関数は、テンプレート全体までの、テンプレートの任意の部分を処理することができます。関数が準拠する必要があるイベントマッピングについては、「CloudFormation マクロ機能インターフェイス」を参照してください。マクロを作成する際の追加の考慮事項については、「CloudFormation マクロ定義を作成する際の考慮事項」を参照してください。
-
AWS::CloudFormation::Macro
リソースタイプを記述したテンプレートを作成します。-
Name
プロパティとFunctionName
プロパティを指定する必要があります。FunctionName
プロパティでは、CloudFormation がマクロを実行するときに呼び出す Lambda 関数の ARN を指定します。 -
デバッグを支援するために、
LogGroupName
およびLogRoleArn
プロパティも指定できます。
-
-
目的のアカウントのマクロを含むテンプレートからスタックを作成するか、管理者アカウントのマクロを参照するテンプレートからセルフマネージド型のアクセス許可を持つスタックセットを作成することで、目的のターゲットアカウントにスタックインスタンスを作成します。
CloudFormation がマクロ定義を含むスタックを正常に作成したら、そのアカウント内でマクロを使用できるようになります。
テンプレートで CloudFormation マクロを使用する
CloudFormation がマクロ定義を含むスタックを正常に作成したら、そのアカウント内でマクロを使用できるようになります。処理するテンプレートの内容に関連する適切な場所で、テンプレート内でマクロを参照して使用します。
CloudFormation マクロの評価順序
テンプレートによっては、CloudFormation がホストするトランスフォーム (AWS::Include 変換 や AWS::Serverless 変換 など) をはじめ複数のマクロを参照できます。
マクロは、テンプレート内の位置に基づいて、最も深く外側にネストされているものから最も一般的なものまで順番に評価されます。テンプレート内の同じ場所にあるマクロは、リストされている順序に基づいて順番に評価されます。
AWS::Include
や AWS::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 を使用して、スタックテンプレートのステージを確認できます。
注記
処理されたスタックテンプレートの最大サイズは、CreateStack
、UpdateStack
、または ValidateTemplate
リクエスト内に直接渡す場合は 51,200 バイトです。Amazon S3 テンプレート URL を使用して S3 オブジェクトとして渡す場合は 1 MB です。ただし、CloudFormation はテンプレート内のマクロを連続的に処理するため、処理中にテンプレートの一時的な状態が更新されます。このため、処理中のテンプレートのサイズは、完全に処理されたテンプレートの許容サイズを一時的に超える場合があります。CloudFormation は、これらのインプロセステンプレートにいくらかのバッファを許可します。ただし、テンプレートやマクロを設計する際は、処理済みのスタックテンプレートの最大許容サイズに留意してください。
テンプレートの処理中に CloudFormation から Transformation data limit exceeded
エラーが返された場合は、CloudFormation で処理中に許容される最大テンプレートサイズを超えています。
この問題を解決するには、以下の対処を検討してください。
-
テンプレートを複数のテンプレートに再構成し、処理中のテンプレートが最大サイズを超えないようにします。例:
-
ネストされたスタックテンプレートを使用して、テンプレートの各パートをカプセル化します。詳細については、「ネストされたスタックを使用して他のスタック内にスタックを埋め込む」を参照してください。
-
複数のスタックを作成し、クロススタック参照を使用してスタック間で情報を交換します。詳細については、「別の CloudFormation スタックのリソース出力を参照する」を参照してください。
-
-
特定のマクロから返されるテンプレートフラグメントのサイズを小さくします。CloudFormation はマクロから返されるフラグメントの内容には干渉しません。
テンプレートで CloudFormation マクロを使用するには
注記
CloudFormation がテンプレートで参照されているマクロを正常に実行するには、ユーザーが基盤となる Lambda 関数に対して Invoke
アクセス権限を持っている必要があります。詳細については、「AWS Lambda デベロッパーガイド」の「AWS Lambda リソースへの許可の管理の概要」を参照してください。
-
テンプレートにマクロへの参照を含めます。
-
テンプレートのスニペットを処理するには、処理したいテンプレートのコンテンツを基準にして配置されている
Fn::Transform
関数内のマクロを参照します。 -
テンプレート全体を処理するには、CloudFormation テンプレートの Transform セクション セクションでマクロを参照してください。
-
-
テンプレートを使用して変更セットを作成します。
重要
スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、
CAPABILITY_AUTO_EXPAND
機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。 -
変更セットの確認および変更セットの実行をします。
重要
スタックセットテンプレートに 1 つ以上のマクロが参照されており、変更セットの結果を確認せずに、処理されたテンプレートから直接スタックセットを作成する必要があります。スタックセットを直接作成または更新するには、CreateStackSet または UpdateStackSet 操作を使用して、
CAPABILITY_AUTO_EXPAND
機能を指定する必要があります。マクロを参照するテンプレートから直接スタックを作成または更新する前に、どのような処理がマクロで実行されるかを確認してください。
マクロの例
このガイドの マクロの例: マクロの作成と使用 チュートリアルに加えて、ソースコードやテンプレートを含むサンプルマクロが GitHub リポジトリ
以下も参照してください。
CloudFormation テンプレートの Transform セクション