AWS CloudFormationでは、テンプレートを柔軟にするために、さまざまな「組み込み関数(Intrinsic Functions)」が用意されています。その中でも、環境やリージョンによって値を切り替えたいときに便利なのが「!FindInMap(FindInMap関数)」です。
この記事では、サンプルコードを用いて、以下の内容をわかりやすく解説します。
!FindInMapの仕組み!FindInMapの基本構文- リージョンや環境ごとに設定を切り替える方法
!Refと組み合わせた使い方
!FindInMapとは?(FindInMap関数)

!FindInMapは、Mappingsセクションに定義した対応表から、指定したキーに合う値を取得する関数です。
たとえば次のようなケースで役立ちます。
- リージョンごとに設定を変えたい
- 開発環境(
dev)と本番環境(prod)で設定を変えたい - OSの種類ごとに設定を変えたい
!FindInMapの基本構文は以下のようになっています。
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]引数の意味は以下の通りです。
| 引数 | 説明 |
|---|---|
MapName | Mappingsセクションで定義したマップの名前 |
TopLevelKey | マップ内の1段目のキー(例:リージョン名や環境名) |
SecondLevelKey | 1段目のキーの下にある2段目のキー(例:AMIやInstanceType) |
MapNameで対応表を選び、TopLevelKey、SecondLevelKeyの順にたどって値を取得します。
なお、!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]は短縮形の構文です。短縮形を使わない場合は、次のように記述します。
Fn::FindInMap: [ MapName, TopLevelKey, SecondLevelKey ]Mappingsセクションの定義
!FindInMapを使うためには、参照先となる対応表をMappingsセクションに定義する必要があります。
例として、リージョンごとに異なるAMI IDを設定したMappingsセクションを見てみましょう。AMI IDは、EC2インスタンスの起動に使用するマシンイメージを識別するIDです。
Mappings:
RegionMap: # ← MapName
ap-northeast-1: # ← TopLevelKey
AMI: ami-0123456789abcdef0 # ← AMIがSecondLevelKey
us-east-1: # ← TopLevelKey
AMI: ami-0abcdef1234567890 # ← AMIがSecondLevelKeyこの例では、RegionMapという対応表の中に、リージョン名を1段目のキー、その下のAMIを2段目のキーとして定義しています。
たとえば、ap-northeast-1の下にあるAMIを指定すると、ami-0123456789abcdef0を取得できます。
掲載しているAMI IDは説明用の例です。実際に使用する場合は、各リージョンで利用できる有効なAMI IDに置き換えてください。
!FindInMapの使い方
次に、!FindInMapを使ったシンプルなサンプルコードを以下に示します。このサンプルコードでは、スタックを作成するリージョンに応じてAMI IDを切り替えています。
Mappings:
RegionMap:
ap-northeast-1:
AMI: ami-0123456789abcdef0
us-east-1:
AMI: ami-0abcdef1234567890
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
InstanceType: t2.microこのサンプルコードでは次のような動きになります。
!Ref "AWS::Region"→ スタックを作成するリージョン名(例:ap-northeast-1)を取得する!FindInMap [RegionMap, ap-northeast-1, AMI]→RegionMapの中から、ap-northeast-1の下にあるAMIの値を取得する
そのため、リージョンがap-northeast-1なら、ImageIdにはami-0123456789abcdef0が設定されます。
あわせて読みたい
続きを見る!Refについては下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。 
【CloudFormation】!Refと!Subの「違い」と「使い分け」を解説!
環境ごとに設定を切り替える例(dev / prod)
MappingsとParametersを組み合わせると、パラメータで指定した環境(dev / prod)に応じて、設定を切り替えることも可能です。
次の例では、EnvTypeで環境を選び、インスタンスタイプとEBSボリュームの容量を切り替えています。AmiIdには、使用するリージョンの有効なAMI IDを指定します。
Mappings:
EnvConfig:
dev:
InstanceType: t2.micro
VolumeSize: "8"
prod:
InstanceType: t3.large
VolumeSize: "20"
Parameters:
EnvType:
Type: String
Default: dev
AllowedValues:
- dev
- prod
AmiId:
Type: AWS::EC2::Image::Id
Description: AMI ID for the EC2 instance
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AmiId
InstanceType: !FindInMap [EnvConfig, !Ref EnvType, InstanceType]
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: !FindInMap [EnvConfig, !Ref EnvType, VolumeSize]EnvTypeに指定した値に応じて、次の設定が選択されます。
devの場合 → インスタンスタイプはt2.micro、ボリューム容量は8 GiBprodの場合 → インスタンスタイプはt3.large、ボリューム容量は20 GiB
EnvTypeの初期値はdevです。本番環境の設定を使う場合は、スタックの作成時や更新時にprodを指定します。
このように、テンプレートを1つ用意しておけば、パラメータ値を変えるだけで環境ごとの設定を切り替えられます。
!FindInMapと!Refの組み合わせ
!FindInMapは、!Refと組み合わせることで、参照するキーをパラメータ値などに応じて切り替えられます。
ここまでの例で使用した、次の3つの記述を見てみましょう。
!FindInMap [RegionMap, !Ref "AWS::Region", AMI]
!FindInMap [EnvConfig, !Ref EnvType, InstanceType]
!FindInMap [EnvConfig, !Ref EnvType, VolumeSize]1つ目では、!Ref "AWS::Region"で取得したリージョン名をTopLevelKeyとして使います。
2つ目と3つ目では、!Ref EnvTypeで取得したdevまたはprodをTopLevelKeyとして使います。その下のInstanceTypeやVolumeSizeを指定することで、必要な値を取得します。
!Refでキーに使う値を取得し、!FindInMapでそのキーに対応する設定値を取得するという流れです。
この組み合わせによって、リージョンや環境ごとにテンプレートを書き分ける手間を減らせます。
本記事のまとめ
この記事ではCloudFormationの!FindInMapについて、以下の内容を説明しました。
!FindInMapは、Mappingsセクションに定義した対応表から、指定したキーに合う値を取得する関数である- リージョンや環境ごとに値を切り替えるときに便利である
!Refと組み合わせることで、リージョン名やパラメータ値に応じて取得する設定値を切り替えられる
お読みいただきありがとうございました。