継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

CloudFormation テンプレートの便利な定義 3選

タダです。

CloudFormation を最近業務でよく使うのですが、自分が使っていてこの定義は便利だなと思ったものがあります。

今回は、その定義 3つをまとめていきます。

  1. Mappings を使ってリソースタグをまとめて設定
  2. Metadata を使って入力パラメータを見やすく管理する
  3. Condition を使って条件判定する

Mappings を使ってリソースタグをまとめて設定

Mappings を使うと、キーと名前付きの一連の値とが対応づけられます。

docs.aws.amazon.com

業務で、大量の AWS リソースに対してタグ付けを行なっているのですが、固定したタグの値が決まっているのであれば、この Mappings を使えば統一的にタグ設定ができます。

例えば、 CloudFormation のコードで以下のように定義します。

下記の定義で、NameタグがEC2_TEST、EnvironmentタグがDEV、SystemIdタグがTESTとタグづけされます。

AWSTemplateFormatVersion: 2010-09-09
Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: ami-0d7ed3ddb85b521a6
      InstanceType: t3.small
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

f:id:sadayoshi_tada:20190223101651p:plain

Metadata を使って入力パラメータを見やすく管理する

Metadata の AWS::CloudFormation::Interface メタデータキーを使うと、テンプレート内のパラメータの順番を制御することができます。

docs.aws.amazon.com docs.aws.amazon.com

テンプレート内で多くのパラメータを扱わなければいけない、かつCloudFormation スタックを画面から作成を行うならばこのオプションを使うのがオススメです。

例えば、以下のテンプレートがあったとします。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  InstanceType:
    Type: String
    Description: (Required) Enter InstanceType.
  ImageId:
    Type: "AWS::EC2::Image::Id"
    Description: (Required) Enter AMI ID.
  DiskSize:
      Type: String
      Description:  (Required) Enter Disk Size.
Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: true
            VolumeSize: !Ref DiskSize
            VolumeType: gp2
      DisableApiTermination: false
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

上記の場合、スタック作成時に次のようなランダムな羅列になります。

f:id:sadayoshi_tada:20190223101759p:plain

この例ではパラメーターが少なくていいですが、ランダムに多数のパラメーターが羅列されるより見やすい形に変更した方が利用しやすいです。

この並びを好みの順番にしたい場合は、次のように定義します。

AWSTemplateFormatVersion: 2010-09-09
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: EC2 Configuration
        Parameters:
          - ImageId
          - InstanceType
          - DiskSize
Parameters:
  InstanceType:
    Type: String
    Description: (Required) Enter InstanceType.
  ImageId:
    Type: "AWS::EC2::Image::Id"
    Description: (Required) Enter AMI ID.
  DiskSize:
      Type: String
      Description:  (Required) Enter Disk Size.
Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: true
            VolumeSize: !Ref DiskSize
            VolumeType: gp2
      DisableApiTermination: false
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

上記に指定すると、ParameterGroupsParameters で指定した順番に羅列されています。

f:id:sadayoshi_tada:20190223101850p:plain

Condition を使って条件判定する

Condition句を使うと、特定の条件の時に、テンプレート内のパラメータ値を自動で変更可能になります。

docs.aws.amazon.com

条件の組み込み関数として、次の定義が可能です。

  • Fn::And : 指定されたすべての条件が true に評価された場合は true を返し、条件のいずれかが false に評価された場合は false を返す
  • Fn::Equals : 2つの値が等しいかどうかを比較し、2つの値が同じ場合は true を返し、同じでない場合は false を返す
  • Fn::If : 指定された条件が true に評価された場合は 1 つの値を返し、指定された条件が false に評価された場合はもう 1 つの値を返す
  • Fn::Not : false と評価された条件に対しては、true を返し、true と評価された条件に対しては、false を返す
  • Fn::Or : 指定された条件のいずれかが true に評価された場合は true を返し、条件のすべてが false に評価された場合は false を返す

具体的に、テンプレートでの定義例を書きます。

下記のように設定することで、Modeパラメーターがprodならば、EBSボリュームはテンプレートが削除されても残りますが、testならば、EBSボリュームは削除されます。

このように使えるので、テンプレート内でのパラメータの使い分けを行う時に便利です。

AWSTemplateFormatVersion: 2010-09-09
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: EC2 Configuration
        Parameters:
          - ImageId
          - InstanceType
          - DiskSize
          - Mode
Parameters:
  InstanceType:
    Type: String
    Description: (Required) Enter InstanceType.
  ImageId:
    Type: "AWS::EC2::Image::Id"
    Description: (Required) Enter AMI ID.
  DiskSize:
      Type: String
      Description:  (Required) Enter Disk Size.
  Mode:
    Default: prod
    AllowedValues:
      - prod
      - test
    Type: String
    Description: (Required) Select mode.
Conditions:
  EC2RunningMode: !Equals [ !Ref Mode, prod]

Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: !If [EC2RunningMode, false, true]
            VolumeSize: !Ref DiskSize
            VolumeType: gp2
      DisableApiTermination: false
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

まとめ

私が業務で扱った CloudFormation テンプレート内の定義で便利だと思ったものを紹介しました。

CloudFormation は自動化していくにあたって欠かせないサービスになるので、活用していきまた別の Tips があったらブログで紹介します。