Include Transformを使ってCFnテンプレートをモジュール化できそう

概要-AWS::Includeとは??

テンプレートに定型コンテンツを挿入するには、AWS Cloud Formation がホストするマクロである AWS::Include transform を使用するのはお勧めです。このマクロはプログラミング言語にの includecopyimportといった構文をイメージすると分かりやすいと思います。一言でいうと、includeマクロは Cloud Formationにおけるプログラミング言語のモジュールに相当する機能 です。S3にアップロードしたCloud Formationのテンプレートを、別のテンプレートからIncludeすることができるようになることです。

AWS::Incloude利点

①他のテンプレートを引用しても1つのスタックを作成する。

②テンプレートの共通化部分は一つのテンプレートにまとめて引用できます。

③ネストスタックの場合は複数のスタックを作成してしまうが、スタック最大作成数の上限に達してしまう問題がありますが。Includeでは一つのスタックのみ作成します。

④あるリソースのプロパティの一部を別テンプレートから呼び出す。

ですので、ある程度AWSのインフラリソースの規模が大きくなってくるとCFnのテンプレートも自然と膨大化になり、保守性が低くなってしまうと思います。AWS:Includeを活用すれば、共通化できると読みやすい範囲でテンプレートを分割したり、何度も繰り返す共通プロパティを一元管理できることになります。

AWS::Incloudeの使用例

テンプレートの最上位、Resourcesの直下、リソース定義の直下、リソースのProperties指定のところなど、いろいろな場所にAWS::includeをおくことができます。

以下のようなテンプレートを例として、Includeを使った場合、構文できるパターンを紹介いたします。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Include Test'
Resources:
  HogeVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.10.0.0/16
  hogeBucket1:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
  hogeBucket2:
    Type: AWS::S3::Bucket
    Properties:
      Tags: 
        -
         Key: name
         Value: hogehoge 

includeを使うと、以下の通りにテンプレート構成できます。

AWSTemplateFormatVersion: '2010-09-09'
# 最上位に置ける
Fn::Transform:
  Name: AWS::Include
  Parameters:
    Location: s3://<incldue-sub-S3バケット>/description.yml
Resources:
  # Resources直下に置ける
  Fn::Transform:
    Name: AWS::Include
    Parameters:
      Location: s3://<incldue-sub-S3バケット>/hogevpc.yml
  hogeBucket1:
    Type: AWS::S3::Bucket
    # 各リソース定義の直下
    Fn::Transform:
      Name: AWS::Include
      Parameters:
        Location: s3://<incldue-sub-S3バケット>/del_policy.yml
  hogeBucket2:
    Type: AWS::S3::Bucket
    Properties:
      # Propertiesの指定に使える
      Fn::Transform:
        Name: AWS::Include
        Parameters:
          Location: s3://<incldue-sub-S3バケット>/tags.yml

IncludeされているサブYAMLファイルは以下の通りです

#description.yml
Description: 'Include Test'
#hogevpc.yml
HogeVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.10.0.0/16
#del_policy.yml
DeletionPolicy: Delete
#tags.yml
Tags: 
    -
     Key: name
     Value: hogehoge 

こういうように構成すると、別のRegionとかにhogeVPCもテンプレートで作成する必要であれば、hogevpc.ymlをそのままIncludeすればOKですね。

ハマってしまったケース

実際のPJではハマってしまったところは1点がありました。

同じレベルの階層では連続的にincludeを定義すると、スタック作成するときにエラーで作成できません。

エラーサンプルは以下の通りです。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Include Test'
Resources:
  Fn::Transform:
    Name: AWS::Include
    Parameters:
      Location: s3://<incldue-sub-S3バケット>/hoge_bucket1.yml
  Fn::Transform:
    Name: AWS::Include
    Parameters:
      Location: s3://<incldue-sub-S3バケット>/hoge_bucket2.yml

対策:Resourceのすべての定義はIncludeすることではなく、Resource名はメインテンプレートに定義して、中身のみIncludeすれば解決できます。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Include Test'
Resources:
 hoge_bucket1:
  Fn::Transform:
    Name: AWS::Include
    Parameters:
      Location: s3://<incldue-sub-S3バケット>/hoge_bucket1.yml
 hoge_bucket2: 
  Fn::Transform:
    Name: AWS::Include
    Parameters:
      Location: s3://<incldue-sub-S3バケット>/hoge_bucket2.yml

いかがでしょうか?テンプレートの定義を再利用する必要な場合はIncludeを使用すると、重複ソースが避けるし、テンプレートの保守性は高くなりますね。この機能はぜひ試してみてください。

Last modified: 2021-04-30

Author