Amazon Web Services ブログ
AWS CloudFormation を AWS Lambda によるマクロで拡張する
今日(2018/9/6)、AWS CloudFormation の強力な新機能である マクロ (Macros) を紹介できることを嬉しく思います。開発者は CloudFormation マクロ を使って CloudFormation テンプレートのネイティブ記法を拡張できるようになりました。これは AWS Lambda による変換処理を呼び出すことで実現されています。みなさんご存知の Serverless Application Model も同様のテクノロジで実現されていますが、今回の機能は、変換処理を、あなたのアカウントの、あなたが作成した Lambdaファンクションを使用して、完全にカスタマイズすることができます。(AWS初心者の方へ)CloudFormation はインフラストラクチャを (YAML や JSON の) コードでモデリングし定義するために重要なツールです。CloudFormation は AWS 全体とそのサービスが依存するコアな構成要素です。
マクロを使うには2つの大きなステップがあります。1つ目はマクロを定義することです。これももちろん CloudFormation テンプレートで定義します。2つ目はマクロを自分のテンプレートで使うことです。全てのテンプレートで使えるように Transform セクションで定義する方法と、内部関数として直接このマクロを呼び出す方法があります。なおこのポストでは「マクロ」、および「変換(トランスフォーム)」、という語句は同様のものとして使います。ではどうやって使うのか見ていきましょう。
CloudFormation マクロ を作る
マクロを作るには2つのコンポーネントが必要です。それは定義と実装です。マクロの定義を作るには、AWS::CloudFormation::Macro
という型の CloudFormation リソースを作成します。これは 使用する Lambda ファンクションの外部仕様を定め、どのようにマクロが呼び出されるかを定義しています。
Type: "AWS::CloudFormation::Macro"
Properties:
Description: String
FunctionName: String
LogGroupName: String
LogRoleARN: String
Name: String
マクロの中で Name
はリージョン内でユニークである必要があります。FunctionName
で参照する Lambda ファンクションはマクロが作られるのと同じリージョンに存在する必要があります。マクロ定義テンプレートを実行すると、そのマクロは他のテンプレートでも利用可能になります。マクロの実体は Lambda ファンクションです。マクロは自分のテンプレートに記述してもよいですし、他のテンプレートとグループにして配置しても良いです。しかしマクロはそれ自体を定義したテンプレートの中では利用することはできません。Lambda ファンクションは以下のような JSON ペイロードを受け取ります。
{
"region": "us-east-1",
"accountId": "$ACCOUNT_ID",
"fragment": { ... },
"transformId": "$TRANSFORM_ID",
"params": { ... },
"requestId": "$REQUEST_ID",
"templateParameterValues": { ... }
}
ペイロードの中の fragment
はテンプレートの全体か、またはテンプレートで処理すべき一部分のどちらかです。これは呼び出し元のテンプレートでどのようにトランスフォームが呼び出されたのかに依存します。テンプレートがYAMLで書かれていても、fragmentには常にJSONが渡されます。
Lambda ファンクションは、シンプルな単一のJSONを返す必要があります。
{
"requestId": "$REQUEST_ID",
"status": "success",
"fragment": { ... }
}
requestId
はインプットペイロードで受け取ったものと同じである必要があります。もし status
が “success” (大文字小文字は区別しません)以外である場合は、ChangeSetの作成は失敗します。ここで、 fragment
は変換済みかつ正しい JSON形式の CloudFormation テンプレート である必要があります。もしファンクションがテンプレートを変更しない場合でも、fragmentには最終的なテンプレートに含まれるべき内容が格納されている必要があります。
CloudFormation マクロを使う
マクロを使うにはシンプルに Fn::Transform
に必要なパラメータを設定して呼び出します。もしテンプレート全体をパースするマクロを使う場合は、テンプレートを Transform セクションのリストに含めます。これは SAMと同じように Transform: [Echo]
といった形で記載します。
テンプレートを実行する際は、各々のマクロが対象のLambdaファンクションを実行し、最終的なテンプレートを返し、ここからチェンジセットが作られます。
ではここでダミーのLambdaファンクションである EchoFunction があったとしましょう。これは渡されたデータをログに記録し、値を変更せずそのまま返します。まず通常のCloudFormationリソースとしてマクロを登録します。このように。
EchoMacro:
Type: "AWS::CloudFormation::Macro"
Properties:
FunctionName: arn:aws:lambda:us-east-1:1234567:function:EchoFunction
Name: EchoMacro
Lambdaファンクションのコードはこのようになります。
def lambda_handler(event, context):
print(event)
return {
"requestId": event['requestId'],
"status": "success",
"fragment": event["fragment"]
}
では、この Lambda ファンクションをデプロイし、マクロを定義する CloudFormation テンプレートを実行します。これで他の CloudFormation テンプレートのトップレベルに定義した Transform セクションから マクロを呼び出すことができます。
AWSTemplateFormatVersion: '2010-09-09'
Transform: [EchoMacro, 'AWS::Serverless-2016-10-31']
Resources:
FancyTable:
Type: AWS::Serverless::SimpleTable
CloudFormationは、まず最初に私たちが定義したEchoMacroを呼び出し、次にAWS::Serverless トランスフォームを呼び出してテンプレートを作り、このテンプレートに対してチェンジセットを作ります。マクロは Transform のリストに書かれた順に実行されます。
マクロは Fn::TransForm
内部関数を使って呼び出すこともできます。この場合はパラメータを渡せます。例えば:
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyS3Bucket:
Type: 'AWS::S3::Bucket'
Fn::Transform:
Name: EchoMacro
Parameters:
Key: Value
インライン変換 は全ての兄弟ノードと小ノードにアクセスできます。変換処理は最も深いものから浅いものに向かって実行されます。つまりトップレベルの変換が最後に実行されます。ええ、みなさんが聞きたいことはわかっていますが…マクロの中にマクロを含めることはできません。
CloudFormationテンプレートを実行しようとすると、チェンジセットを作成するかどうか聞いてきます。デプロイの前にその内容をプレビューすることができます。
マクロの例
マクロを作成しようと考える開発者のみなさんを助けるため、多くの リファレンス を用意しました。私たちは多くの人にマクロを公開してほしいと思っています。これらの4つはAWS社内のミニハッカソン(事前にこの機能を使って行いました)の勝利者です。
名前 | 説明 | 作成者 |
PyPlate | テンプレートにインラインPython処理を記述する | Jay McConnel – Partner SA |
ShortHand | CloudFormationリソース定義の記述を短くする | Steve Engledow – Solutions Builder |
StackMetrics | スタックのCloudWatchメトリクス | Steve Engledow と Jason Gregson – Global SA |
String Functions | テンプレートで使える共通の文字列関数 | Jay McConnel – Partner SA |
以下は実装してみると面白そうだと思うアイディアです。
- R53への自動登録 + AWS Certificate Manager (ACM) 証明書のプロビジョニング
- S3の静的ウェブサイト設定自動化 または カスタムドメインによる Amazon CloudFront ディストリビューション
- CloudFormation の Mappings定義を DynamoDB テーブルから読むようにする
- Amazon Virtual Private Cloud の IPv6 設定自動化
- Slack, Twitter, Messenger への Webhook サブスクリプション自動化
もしクールなアイディアを実装したら、周囲に広めてくれると嬉しいです!
今すぐつかえます
CloudFormationマクロはLambdaが使える全てのリージョンで本日から使えます。マクロを使うために CloudFormation に追加のコストは必要ありません。AWS Lambda の実行にかかる通常の費用のみです。ドキュメントにはマクロ作成に役立つ、より詳しい情報があります。
マクロは、私が CloudFormation の機能中で最も気に入っているものの一つです。みなさんがマクロを使って素晴らしいものを作ってくれるのを楽しみにしています。マクロは あなたがコードで定義したインフラストラクチャを、コードでさらに機能強化するために役立ちます。この新機能が提供する可能性は無限大です!
– Randall
原文は こちら (Extending AWS CloudFormation with AWS Lambda Powered Macro)。翻訳は SA 大村が担当しました。