まえがき
AWS CloudFormationのテンプレートを書いていると長くなることがよくありますが、数千行を超えると読む気が失せると思います。
そんな長くなりがちなテンプレートを分割する方法を説明します。
テンプレートの分割について
ネストされたスタック
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html
テンプレート
IAMユーザーを作成するテンプレートを参考に分割します。
分割前
Parameters:
# パラメータ名がUserNameParameter データ型がString
UserNameParameter:
Type: String
TagNames:
Type: String
Resources:
MyIAMUser:
Type: 'AWS::IAM::User'
Properties:
# !RefでパラメータのUserNameParameterを参照
UserName: !Ref UserNameParameter
# !RefでパラメータのTagNamesを参照
Tags:
- Key: "tagname01"
Value: !Ref TagNames
分割するための書式
Resources
セクションに以下を指定してください。
-
Type
にAWS::CloudFormation::Stack
-
Properties
のTemplateURL
に参照先のAmazon S3 バケットにあるテンプレート
Resources:
SampleIam:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL:https://sample-s3bucket.s3.ap-northeast-1.amazonaws.com/prefix/NestTemplate.yaml
詳細はAWSドキュメントのCloudFormationユーザーガイドのAWS::CloudFormation::Stackに記載されています。
方法①参照先を絶対パスで記載する
参照先のS3 バケットにあるテンプレートを絶対パスで指定します。
準備
テンプレートの分割
今回はIAMユーザー作成部分だけ子テンプレートに切り出す形で分割します。
あまり意味はないですが、親テンプレートにはタグ指定だけ残しています。
Parameters:
# パラメータ名がUserNameParameter データ型がString
UserNameParameter:
Type: String
TagNames:
Type: String
Resources:
MyIAMUserSplit:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://sample-s3bucket.s3.ap-northeast-1.amazonaws.com/stack_sample/iam_user_create_child_001.yaml
Parameters:
ChildParameter: !Ref UserNameParameter
# !RefでパラメータのTagNamesを参照
Tags:
- Key: "tagname01"
Value: !Ref TagNames
Parameters:
# 親から引き継いだパラメータ名がChildParameter データ型がString
ChildParameter:
Type: String
Resources:
MyIAMUserSplit:
Type: 'AWS::IAM::User'
Properties:
# !Refで親から引き継いだパラメータのChildParameterを参照
UserName: !Ref ChildParameter
S3に格納
動作確認
AWSコンソールからスタックを作成します。スタック名はparent-sample
にします。
方法②参照先を相対パスで記載する
前述の方法でも分割可能ですが、ネストするファイルが多い場合、参照先のURLをすべて書き換えるのが煩わしくなります。
他にも本番環境や開発環境でAWSアカウントが異なる場合等も書き換えが手間です。
解決方法としてcloudformation package
を使う方法があります。
準備
この方法の場合、TemplateURLに記載する参照先は相対パスになります。先ほどと異なりS3への格納は不要です。
.
┣ iam_user_create_parent_001.yaml
┗ iam_user_create_child_001.yaml
Parameters:
UserNameParameter:
Type: String
TagNames:
Type: String
Resources:
MyIAMUserSplit:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ./iam_user_create_child_001.yaml
Parameters:
ChildParameter: !Ref UserNameParameter
Tags:
- Key: "tagname01"
Value: !Ref TagNames
コマンド実行
-
cloudformation package
コマンドから親テンプレートを作成します。
aws cloudformation package --template-file {親テンプレート} --s3-bucket {アップロード先バケット名} --output-template-file {作成されるテンプレートファイル名}
このコマンドでは以下のことが行われます。- 相対パスで指定した子テンプレートファイルがS3にアップロードされる。
- S3にアップロードされた子テンプレートを参照する親テンプレートが作成される。
コマンドaws cloudformation package --template-file iam_user_create_parent_001.yaml --s3-bucket sample-s3bucket --s3-prefix Nested_Stack --output-template-file packaged.yaml
cloudformation package
コマンドで指定するテンプレートに日本語のコメントがあると、'cp932' codec can't decode byte
のメッセージを理由に失敗します。
コマンド実行結果
実行結果のS3とテンプレートは以下の通りです。
S3の状態
名前と拡張子が変更されていますが、格納されているファイルが子テンプレートになります。
テンプレート
packaged.yaml
が作成されました。このテンプレートのTemplateURL
がS3の子テンプレートになっています。
親テンプレート・子テンプレートともに記載が少し変更されていますが、内容に変わりはありません。
Parameters:
UserNameParameter:
Type: String
TagNames:
Type: String
Resources:
MyIAMUserSplit:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.ap-northeast-1.amazonaws.com/sample-s3bucket/Nested_Stack/373e20f4f658ea58c1fe32a145232a4c.template
Parameters:
ChildParameter:
Ref: UserNameParameter
Tags:
- Key: tagname01
Value:
Ref: TagNames
Parameters:
ChildParameter:
Type: String
Resources:
MyIAMUserSplit:
Type: AWS::IAM::User
Properties:
UserName:
Ref: ChildParameter
動作確認
AWSコンソールからスタックを作成します。スタック名はparent-sample-Nested-Stack
にします。
あとがき
テンプレートの分割方法を忘れかけていたので備忘も兼ねてまとめてみました。