【AWS】CloudFormation ~ Mappings ~

■ はじめに

AWS CloudFormationで、
環境 (dev/stage/prod) によって値を切り替えたい。

https://dk521123.hatenablog.com/entry/2022/07/02/214543

で、条件分岐を行ったが、それ以外の方法で、
Mappings が使えそうなので、調べてみた

目次

【1】Mappings
【2】利点
 1)可読性・拡張性の良さ
 2)AWSコスト削減
 3)セキュリティ強化
【3】定義
【4】値の参照
 1)組み込み関数 !FindInMap / Fn::FindInMap
【5】サンプル
 例1:環境によってインスタンスタイプを変更する
 例2:環境によってKMSキーポリシーのPrincipalを切り替える

【1】Mappings

* キー・バリュー型の定数を定義できる
* 値は String または List 
* 指定した値は、「Resources」で使用できる

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

【2】利点

Mappings を使った値を切り替えることは、
個人的には以下の恩恵を受けられると思う

1)可読性・拡張性の良さ

* 以下の関連記事で扱った Conditions セクション / 条件関数 !IF を
 使った切り替えより、圧倒的に可読性・拡張性の高いコードになる

CloudFormation ~ 条件分岐 ~
https://dk521123.hatenablog.com/entry/2022/07/02/214543

2)AWSコスト削減

* 「【5】サンプル」の「例1」のように、
 InstanceTypeを切り替えることにより
 コストを節約することが可能

3)セキュリティ強化

* 「【5】サンプル」の「例2」のように、
 IAM Policy でAllowする際に、必要な部分のみ許可するので
 セキュリティ強化につながる

【3】定義

  Mappings:
    # Mappings「MapperForEnv」を定義
    MapperForEnv:
      # キー
      dev:
        # バリュー(devだったら、この値になる)
        ConfFilePath: "conf/dev.yaml"
      stage: 
        ConfFilePath: "conf/stage.yaml"
      prod: 
        ConfFilePath: "conf/prod.yaml"

複数定義する場合

Mappings:
  EnvMapper:
    dev:
      AwsAccountId: 11111111111111
      VpcCidr: 10.0.3.0/24
      InstanceType: t2.micro
      # List も使える
      S3BucketArns:
        - arn:aws:s3::::your-s3-bucket-dev-1
        - arn:aws:s3::::your-s3-bucket-dev-1/*
        - arn:aws:s3::::your-s3-bucket-dev-2
        - arn:aws:s3::::your-s3-bucket-dev-2/*
    stage:
      AwsAccountId: 222222222222222
      VpcCidr: 10.0.2.0/24
      InstanceType: t2.small
      S3BucketArns:
        - arn:aws:s3::::your-s3-bucket-stage-1
        - arn:aws:s3::::your-s3-bucket-stage-1/*
        - arn:aws:s3::::your-s3-bucket-stage-2
        - arn:aws:s3::::your-s3-bucket-stage-2/*
    prod:
      AwsAccountId: 33333333333333
      VpcCidr: 10.0.1.0/24
      InstanceType: t2.medium
      S3BucketArns:
        - arn:aws:s3::::your-s3-bucket-prod-1
        - arn:aws:s3::::your-s3-bucket-prod-1/*
        - arn:aws:s3::::your-s3-bucket-prod-2
        - arn:aws:s3::::your-s3-bucket-prod-2/*

【4】値の参照

* 組み込み関数 !FindInMap / Fn::FindInMap を使って参照する
* なお、組み込み関数に関する詳細は、以下の関連記事を参照

CloudFormation ~ 組み込み関数 ~
https://dk521123.hatenablog.com/entry/2021/12/04/202519

例:「【3】定義」のサンプルを参照する場合

Value: !FindInMap [MapperForEnv, !Ref EnvironmentType, ConfFilePath]

1)組み込み関数 !FindInMap / Fn::FindInMap

* Mappings セクションで宣言されたマップのキーに対応する値を返却

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html

# 完全名関数の構文
Fn::FindInMap: [ MapName, TopLevelKey, SecondLevelKey ]

# 短縮形の構文
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]

第1引数:MapName

* Mappings セクションで宣言された、キーと値を含むマッピングの論理名

第2引数:TopLevelKey

* 最上位のキー名。この値は、キーと値のペアのリスト

SecondLevelKey

* 2 番目のレベルのキー名で、
 TopLevelKey に割り当てられたリストのキーの 1 つに設定。

【5】サンプル

例1:環境によってインスタンスタイプを変更する

AWSTemplateFormatVersion: "2010-09-09"
Description: This is a sample

Parameters:
  Env:
    Description: Environment.
    Type: String
    AllowedValues:
      - dev
      - stage
      - prod
    Default: dev

Mappings:
  InstanceTypeMapper:
    dev:
      InstanceType : t2.micro
    stage:
      InstanceType : t2.small
    prod:
      InstanceType: t2.medium

Resources:
  DemoEC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType : !FindInMap [InstanceTypeMapper, !Ref Env, InstanceType]

# [別の書き方]
#      InstanceType: !FindInMap
#        - InstanceTypeMapper
#        - !Ref Env
#        - InstanceType

例2:環境によってKMSキーポリシーのPrincipalを切り替える

AWSTemplateFormatVersion: "2010-09-09"
Description: "This is a demo for KMS"

Parameters:
  Env:
    Description: Environment
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - stage
      - prod

Mappings:
  EnvMapper:
    dev:
      RoleForKms: arn:aws:iam::11111111111:role/dev-role
    stage:
      RoleForKms: arn:aws:iam::22222222222:role/stg-role
    prod:
      RoleForKms: arn:aws:iam::33333333333:role/prd-role

Resources:
  # -------
  # KMS Key
  # -------
  DemoKmsKey:
    Type: "AWS::KMS::Key"
    Properties:
      Description: This is a demo key for KMKS
      EnableKeyRotation: true
      KeyPolicy:
        Version: 2012-10-17
        Id: key-demo-1
        Statement:
          - Sid: Enable IAM User Permissions
            Effect: Allow
            Principal:
              AWS: !FindInMap [EnvMapper, !Ref Env, RoleForKms]
            Action: kms:*
            Resource: "*"
      Tags:
        - Key: Name
          Value: !Sub demo-key-${Env}-cmk
  # -------
  # KMS Alias
  # -------
  DemoKmsKeyAlias:
    Type: "AWS::KMS::Alias"
    Properties:
      AliasName: !Sub alias/demo-key-${Env}-cmk
      TargetKeyId: !Ref DemoKmsKey
Outputs:
  DemoKmsKey:
    Value: !GetAtt DemoKmsKey.Arn
    Description: "This output is a demo KMS key"
    Export:
      Name: !Sub demo-key-${Env}-cmk

関連記事

CloudFormation ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2024/02/10/231900
CloudFormation ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2021/10/26/224812
CloudFormation ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2021/12/01/170326
CloudFormation ~ 開発環境 ~
https://dk521123.hatenablog.com/entry/2022/05/22/000000
CloudFormation ~ 組み込み関数 ~
https://dk521123.hatenablog.com/entry/2021/12/04/202519
CloudFormation ~ 条件分岐 ~
https://dk521123.hatenablog.com/entry/2022/07/02/214543
CloudFormation ~ Parameters ~
https://dk521123.hatenablog.com/entry/2024/02/29/220042
CloudFormation ~ 疑似パラメータ ~
https://dk521123.hatenablog.com/entry/2021/12/05/134313
CloudFormation ~ DeletionPolicy 属性 ~
https://dk521123.hatenablog.com/entry/2021/12/27/211328
CloudFormation ~ 認証情報の扱い ~
https://dk521123.hatenablog.com/entry/2021/12/28/224501
CloudFormation ~ S3 ~
https://dk521123.hatenablog.com/entry/2022/05/25/220037
CloudFormation ~ KMS ~
https://dk521123.hatenablog.com/entry/2022/05/26/112627
CloudFormation ~ IAM ~
https://dk521123.hatenablog.com/entry/2022/05/27/100820
CloudFormation ~ EC2 ~
https://dk521123.hatenablog.com/entry/2024/02/11/010935
CloudFormation で Github/CodePipeline/CodeBuild を構築する
https://dk521123.hatenablog.com/entry/2021/12/26/155956
CloudFormation でのトラブル
https://dk521123.hatenablog.com/entry/2022/05/30/191507
CloudFormationで変数を参照したら、エラー「Unresolved resource dependencies」が表示
https://dk521123.hatenablog.com/entry/2024/02/27/211050
シェル ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2014/10/23/005406
シェル ~ Shebang
https://dk521123.hatenablog.com/entry/2024/02/02/000000
ヒアドキュメント ~ 複数行の テキストをファイル出力する ~
https://dk521123.hatenablog.com/entry/2016/05/13/231535
シェル ~ インストール済みかどうか調べる ~
https://dk521123.hatenablog.com/entry/2024/03/02/000000