マッピング: テンプレートの汎用性を高める。

2021.11.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

"Infrastructure as Code"という概念は、クラウド・DevOpsやクラウド・アーキテクチャーにおける最も重要な側面の一つです。これは、環境をインスタンス化して構成するプログラム的な方法です、セルフドキュメント化されているだけでなく、再現性もあります。クラウドデプロイメントのパーツをコード化することで、インフラを何度も予測可能に構築できる手順を開発することができ、人為的なミスによる設定ミスや失敗の可能性を排除することができます。

AWSでは、CloudFormationがこれらの目標を達成するための主要なツールです。エンジニアはCloudFormationを使ってテンプレートを構築し、AWS内にリンクされたリソースのスタックを作成します。

パラメーター

パラメータは、CloudFormationテンプレートに柔軟性を与え、複数のコンテキストで再利用できるようにするためによく使われます。しかし、自分だけでなく誰もが再利用できるテンプレートにしたい場合、環境ごとに異なる構成設定が必要になります。また、エンドユーザーがテンプレートの項目の値を変更することはできません。 そのため、CloudFormationには2つの特徴があります。

  1. マッピング: これは、リソース宣言で使用するために、キーと値のセット「Key:Value」辞書にマッチさせます。.
  2. コンディション: これにより、論理的なステートメントを追加して、リソースの値を追加または変更することができます。

マッピング

  1. マッピングは、CloudFormationテンプレート内の固定変数で、名前と値のペアで構成されています。
  2. これらは、テストと本番、異なるリージョン、異なるAMIタイプなど、異なる環境を区別したい場合に非常に便利です。

マッピングの例:

Mappings:
  RegionEC2ImageMap:
    ap-northeast-3: 
      HVM64: "ami-09ec82600a05bc23a"
    ap-northeast-1: 
      HVM64: "ami-09c4848c1c6c4b09b"
    ap-southeast-1: 
      HVM64: "ami-082105f875acab993"
  InstanceType:
    test:
      EnvInstanceType: t2.micro
    prod:
      EnvInstanceType: t2.small

上の例では、"RegionEC2ImageMap "と "InstanceType "という2つのトップレベルの値があります、"RegionEC2ImageMap "には "Regions"、"InstanceType "には "test", "prod "という複数のセカンドキーがあります。

上記のMappingの値にアクセスするには、"FN::FindInMap "という関数を使用する必要があります。

Resources:
  EC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId!FindInMap[RegionMap, !Ref "AWS::Region::HVM64"]
      InstanceType: t2.micro

では、テンプレートのサンプルを見てみましょう。

Parameters: 
    EnvironmentType: 
      Description: The environment type
      Type: String
      Default: testing
      AllowedValues: 
        - testing
        - prod
      ConstraintDescription: must be a testing or prod
Mappings:
  RegionEC2ImageMap:
    ap-northeast-3: 
      HVM64: "ami-09ec82600a05bc23a"
    ap-northeast-1: 
      HVM64: "ami-09c4848c1c6c4b09b"
    ap-southeast-1: 
      HVM64: "ami-082105f875acab993"
  EnvToInstanceType:
    testing:
      EnvInstanceType: t2.micro
    prod:
      instanceType: t2.small    

Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap
        - RegionEC2ImageMap
        - !Ref 'AWS::Region'
        - HVM64
      InstanceType: !FindInMap
        - EnvToInstanceType
        - !Ref 'EnvironmentType'
        - EnvInstanceType

マッピングは主に、以下のような環境で使用できるすべての値を知っている場合に使用されます。

  • Region
  • AWS Account
  • Availability Zone
  • Environment
  • etc...

マッピングを使用すると、テンプレート内で許可された値をある程度コントロールすることができ、他のユーザーとテンプレートを共有するのに役立ちます。

コンディション

コンディションでは、論理的なステートメントを追加して、リソースの値を追加または変更することができます。

  1. コンディションは、与えられたコンディションに基づいてリソースや出力の作成を制御するために使用されます。
  2. コンディションは何でも構いませんが、一般的なものは以下の通りです。
    • Environment(dev/test)
    • AWS Region
    • Parameter Value
  3. コンディションは、別の条件、パラメータ値、マッピングを参照することができます。
  4. Logical function can be any of the following:
    • Fn::Equals
    • Fn::And
    • Fn::If
    • Fn::Not
    • Fn::Or

コンディションの例:

Conditions:
  CreateTestRes: !Equals [!Ref EnvType, test ]

コンディションを使って:

Resources:
  MountPoint:
    Type: AWS::EC2::VolumeAttachment
    Condition::CreateTestRes

上のコンディションは、EC2ボリュームが添付されたマウントポイントを持つ「リソース」の例で、コンディションはCreateTestResourcesなので、コンディションがtrueの場合はこのマウントポイントが作成され、falseの場合は作成されないことを示しています。

より理解を深めるために、テンプレートのサンプルを見てみましょう。

Parameters:  
  ImageId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  EnvType:
    Description: Environment type.
    Default: test
    Type: String
    AllowedValues:
      - prod
      - test
    ConstraintDescription: must specify prod or test.

Conditions:
  CreateProdRes: !Equals [ !Ref EnvType, prod ]

Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref ImageId
      InstanceType: t2.micro

  MountPoint:
    Type: AWS::EC2::VolumeAttachment
    Condition: CreateProdRes
    Properties:
      InstanceId:
        !Ref EC2Instance
      VolumeId:
        !Ref NewVolume
      Device: /dev/sdh

  NewVolume:
    Type: AWS::EC2::Volume
    Condition: CreateProdRes
    Properties:
      Size: 1
      AvailabilityZone:
        !GetAtt EC2Instance.AvailabilityZone

Outputs:
  VolumeId:
    Condition: CreateProdRes
    Value:
      !Ref NewVolume

上のテンプレートでは、「prod」と「test」の2つの環境があります、テンプレートの実行時にどのパラメータを選択するかによって、対応するコンディションが実行されます。

まとめ:

CloudFormationのマッピングとコンディションを組み合わせることで、より汎用性の高いテンプレートを作成することができます、異なる環境の状況に合わせてパラメータを多用した共有不可能なテンプレートを排除することができます。

マッピングとコンディションを併用することで、許可された値やリソースをより適切に管理することができます。これにより、ワークロードの要件が異なる異なる地域に住む様々なチームや顧客と共有できるテンプレートが作成されます。

参考リンク:

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html