1
1

CloudFormationのテンプレートを分割したくなりませんか?

Last updated at Posted at 2024-07-25

まえがき

AWS CloudFormationのテンプレートを書いていると長くなることがよくありますが、数千行を超えると読む気が失せると思います。
そんな長くなりがちなテンプレートを分割する方法を説明します。

テンプレートの分割について

ネストされたスタック
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html

テンプレート

IAMユーザーを作成するテンプレートを参考に分割します。

分割前

iam_user_create.yaml
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セクションに以下を指定してください。

  • TypeAWS::CloudFormation::Stack
  • PropertiesTemplateURLに参照先の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ユーザー作成部分だけ子テンプレートに切り出す形で分割します。
あまり意味はないですが、親テンプレートにはタグ指定だけ残しています。

親テンプレート(iam_user_create_parent_001.yaml)
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 
子テンプレート(iam_user_create_child_001.yaml)
Parameters:
  # 親から引き継いだパラメータ名がChildParameter データ型がString
  ChildParameter: 
    Type: String
Resources:
  MyIAMUserSplit:
    Type: 'AWS::IAM::User'
    Properties:
      # !Refで親から引き継いだパラメータのChildParameterを参照
      UserName: !Ref ChildParameter

S3に格納

分割したファイルをS3に格納します。
スクリーンショット 2024-07-03 114622.png

動作確認

AWSコンソールからスタックを作成します。スタック名はparent-sampleにします。

  • テンプレートの指定で、親テンプレートのurlを指定します
    スクリーンショット 2024-07-03 195518_edit.png
  • 正常にparent-sampleとネストされたスタックが作成されました。(IAMユーザーも作成されています。)
    スクリーンショット 2024-07-03 115140.png

方法②参照先を相対パスで記載する

前述の方法でも分割可能ですが、ネストするファイルが多い場合、参照先のURLをすべて書き換えるのが煩わしくなります。
他にも本番環境や開発環境でAWSアカウントが異なる場合等も書き換えが手間です。

解決方法としてcloudformation packageを使う方法があります。

準備

この方法の場合、TemplateURLに記載する参照先は相対パスになります。先ほどと異なりS3への格納は不要です。

構成
.
┣ iam_user_create_parent_001.yaml
┗ iam_user_create_child_001.yaml
親テンプレート(iam_user_create_parent_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の状態

名前と拡張子が変更されていますが、格納されているファイルが子テンプレートになります。
スクリーンショット 2024-07-04 010632.png

テンプレート

packaged.yamlが作成されました。このテンプレートのTemplateURLがS3の子テンプレートになっています。
親テンプレート・子テンプレートともに記載が少し変更されていますが、内容に変わりはありません。

親テンプレート(packaged.yaml)
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にします。

  • テンプレートソースの指定は、親テンプレートのファイルをアップロードします。
    スクリーンショット 2024-07-04 013224.png

  • スタック作成を実行すると正常にスタックが作られました。
    スクリーンショット 2024-07-03 115140.png

あとがき

テンプレートの分割方法を忘れかけていたので備忘も兼ねてまとめてみました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1