この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
CX事業本部@大阪の岩田です。
CloudFormationのAWS:Include
を使うと、CloudFormationのテンプレート内に別テンプレートの中身を読み込むことができます。私も以下の記事を参考にSwaggerの定義を分離するのに愛用しています。
CloudFromationのAWS::Includeを利用してAWS SAMからインラインSwaggerを分離して管理する
このAWS:Include、恥ずかしながらリソースのプロパティを定義する際にしか利用できないと思いこんでいたのですが、実はもっと色々な場所で利用できることに気付きました。ご存知の人も多いかもしれませんが、改めてご紹介します。
AWS:Includeとは??
S3上に置かれたファイルの中身をCloudFormationのテンプレート内に読み込むためのマクロです。公式ドキュメントに記載されているように、プログラミング言語における include
、copy
、import
といった構文をイメージすると分かり良いと思います。前述の中山のブログが執筆された時点ではAWS CLIによるpackageが未対応だったのですが、今は普通に対応しているので、S3にアップロードする手間をあまり意識することなく利用できます。
AWS:Includeの利用例
実際のテンプレートを見て頂くのが早いと思います。以下のように
- テンプレートの最上位
- Resourcesの直下
- リソース定義の直下
- リソースのProperties指定
色んな場所にAWS:Includeを置くことができます
include_test.ym
AWSTemplateFormatVersion: '2010-09-09'
# 最上位にも置けるし
Fn::Transform:
Name: AWS::Include
Parameters:
Location: description.yml
Resources:
# Resources直下にも置けるし
Fn::Transform:
Name: AWS::Include
Parameters:
Location: dynamodb.yml
TestBucket1:
Type: AWS::S3::Bucket
# 各リソース定義の直下もOK
Fn::Transform:
Name: AWS::Include
Parameters:
Location: del_policy.yml
TestBucket2:
Type: AWS::S3::Bucket
Properties:
# Propertiesの指定にも使えるし
Fn::Transform:
Name: AWS::Include
Parameters:
Location: tags.yml
TestBucket3:
Type: AWS::S3::Bucket
Fn::Transform:
Name: AWS::Include
Parameters:
Location: del_policy.yml
Properties:
WebsiteConfiguration:
IndexDocument: index.html
# 1つのリソースに複数回Includeを使ったり
# PropertiesをマージしたりしてもOK
Fn::Transform:
Name: AWS::Include
Parameters:
Location: tags.yml
Includeしている各YAMLファイルは以下の通りです
description.yml
Description: 'Include Test'
dynamodb.yml
TestTable:
Type: "AWS::DynamoDB::Table"
Properties:
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "N"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
BillingMode: PAY_PER_REQUEST
del_policy.yml
DeletionPolicy: Delete
tags.yml
Tags:
-
Key: SomeKey
Value: SomeVal
dynamodb.yml
ではリソースの定義を丸々記述しています。このようにDynamoDB用のテンプレート、Lambda用のテンプレート...といった形でサービス単位である程度テンプレートを分けておくと保守性を高く保ちやすくなります(あまり分けすぎでも逆にややこしくなるのでケースバイケースですが)。また、tags.yml
のように各リソースで共通設定するプロパティだけ切り出せば、冗長な記述を削減することも可能です。
Packageしてみる
先程のテンプレートに対してcloudformationのpackageコマンドを実行してみます。これでinclude対象に指定された各ファイルがS3にアップロードされ、デプロイ用のテンプレートファイルが出力されます。
$ aws cloudformation package --template-file include_test.yml --s3-bucket <適当なS3バケット> --output-template-file output.yml
出力されたファイルはこちらです。
output.yml
AWSTemplateFormatVersion: '2010-09-09'
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://<package時に指定したS3バケット>/b7a2955ca33cb3908c36b49284fd487a
Resources:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://<package時に指定したS3バケット>/44f286194fbdc0705011eba5aa2e8c47
TestBucket1:
Type: AWS::S3::Bucket
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://<package時に指定したS3バケット>/3b8fa7b7a78df4b066b7b7a3851c4802
TestBucket2:
Type: AWS::S3::Bucket
Properties:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://<package時に指定したS3バケット>/4c8b60a22160fe0bb6a822088ccddb71
TestBucket3:
Type: AWS::S3::Bucket
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://<package時に指定したS3バケット>/3b8fa7b7a78df4b066b7b7a3851c4802
Properties:
WebsiteConfiguration:
IndexDocument: index.html
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://<package時に指定したS3バケット>/4c8b60a22160fe0bb6a822088ccddb71
デプロイしてみる
packageしたテンプレートを使ってスタックを作成してみましょう
$ aws cloudformation deploy --template-file output.yml --stack-name <適当なスタック名> --capabilities CAPABILITY_IAM
無事にデプロイできました!
AWS:Includeで各テンプレートをIncludeした最終的なテンプレートが「処理されたテンプレートの表示」から確認できます。JSON形式で出力されているので、YAMLに変換すると以下のようになります。
AWSTemplateFormatVersion: '2010-09-09'
Description: Include Test
Resources:
TestBucket2:
Type: AWS::S3::Bucket
Properties:
Tags:
- Key: SomeKey
Value: SomeVal
TestBucket3:
Type: AWS::S3::Bucket
Properties:
WebsiteConfiguration:
IndexDocument: index.html
Tags:
- Key: SomeKey
Value: SomeVal
DeletionPolicy: Delete
TestBucket1:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
TestTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: N
KeySchema:
- AttributeName: id
KeyType: HASH
BillingMode: PAY_PER_REQUEST
Includeしたファイルの中身がマージされて、1つのテンプレートに統合されていることが分かります。
まとめ
CloudFormationのAWS:Include
は色んな場所で利用できますというご紹介でした。ある程度インフラの規模が大きくなってくるとCloudFormationのテンプレートも自然と肥大化し、保守性が低くなってしまいます。AWS:Include
をうまく活用することで、読みやすい範囲でテンプレートを分割したり、何度も繰り返す共通プロパティを一元管理するといったことが可能になるので、良ければ利用を検討してみて下さい。