AWS 環境でインフラストラクチャをコードとして管理する際、AWS CloudFormation は強力なツールです。
しかし、マルチリージョン展開を行う場合、特に AMI(Amazon Machine Image) などのリージョン固有のリソースを扱うときには注意が必要です。
CloudFormation の Mappings セクションを活用して、リージョン間で異なるリソースを動的に参照し、テンプレートの再利用性を高める方法について
なぜ Mappings が必要なのか?
-
AMI はリージョンごとに異なる
AMI は EC2 インスタンスの OS やアプリケーション設定を含むイメージです。
しかし、AMI はリージョンごとに異なる ID を持ちます。
同じイメージでも、リージョンが異なれば AMI ID も異なります。 -
問題点
テンプレート内で AMI ID をハードコードすると、そのテンプレートは
特定のリージョンでしか動作しません。
他のリージョンでスタックを作成しようとすると
AMI ID が存在しないためエラーになります。
Mappings セクションで解決する
-
Mappings の基本
Mappings セクションは、CloudFormation テンプレート内で固定のキーと値のペアを定義するためのセクションです。
条件によって異なる値を取得する際に便利です。 -
AWS::Region 疑似パラメータ
AWS::Region は、テンプレートが実行されているリージョン名を自動的に取得するための疑似パラメータです。
これを使用することで、テンプレートをリージョンに依存しない形で記述できます。
実装手順
Mappings セクションを定義する
まず、テンプレート内で各リージョンに対応する AMI ID を定義します。
Mappings:
RegionMap:
us-east-1:
AMI: ami-0abcdef1234567890
us-west-1:
AMI: ami-0fedcba0987654321
ap-northeast-1:
AMI: ami-0123456789abcdef0
# 他のリージョンも同様に追加
• RegionMap:マッピングの名前
• us-east-1:リージョン名
• AMI:キーとなる属性名
• ami-xxxxxxxx:そのリージョンでの AMI ID
リソース定義でマッピングを参照する
次に、EC2 インスタンスなどのリソース定義で、AMI ID を直接指定するのではなく、Mappings から取得します。
Resources:
MyEC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: !FindInMap
- RegionMap # マッピング名
- !Ref 'AWS::Region' # 現在のリージョン名を取得
- AMI # 取得したいキー名
InstanceType: t2.micro
# 他のプロパティ
• !FindInMap [マッピング名, キー, サブキー]:Mappings から値を取得する関数
• !Ref 'AWS::Region':現在のリージョン名を取得
動的な AMI ID の取得
上記の設定により、テンプレートがどのリージョンで実行されても、対応する AMI ID が自動的に選択されます。
補足:他のリソースでも活用可能
Mappings は AMI ID 以外にも、リージョンや環境ごとに異なる値を動的に設定する際に活用できます。
例:リージョンごとの S3 バケット名
Mappings:
RegionBucketMap:
us-east-1:
BucketName: my-bucket-us-east
us-west-1:
BucketName: my-bucket-us-west
ap-northeast-1:
BucketName: my-bucket-ap-northeast
リソース定義で参照
Resources:
MyS3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !FindInMap
- RegionBucketMap
- !Ref 'AWS::Region'
- BucketName