BioErrorLog Tech Blog

試行錯誤の記録

!FindInMapを!Subの中で使う | CloudFormation

AWS CloudFormationで!FindInMap!Sub内で使うやり方をまとめます。

はじめに

こんにちは、@bioerrorlogです。

CloudFormationの!Subは値を代入/置換 ("substitute")できる関数、!FindInMapMappingsから値を取得できる関数です。
(!SubFn::Subの短縮記法、!FindInMapFn::FindInMapの短縮記法)

典型的な使い方は、ざっくりこんな感じでしょうか:

# !Sub の使用例:
ExampleArn: !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/instance-id'
# -> ${AWS::Region}と${AWS::AccountId}が文字列に代入される

# !FindInMapの使用例:
Mappings: 
  RegionMap: 
    us-east-1: 
      "HVM64": "ami-0ff8a91507f77f867"
    us-west-1: 
      "HVM64": "ami-0bdb828fd58c52235"
Resources: 
  myEC2Instance: 
    Type: "AWS::EC2::Instance"
    Properties: 
      ImageId: !FindInMap [ RegionMap, !Ref 'AWS::Region', HVM64 ]
# -> Mappingsから該当の値が取得される


ここでこの二つの関数を組み合わせて、!FindInMapで取得した値を!Subで文字列に代入したくなるときがあります。

今回はそのやり方、!FindInMap!Subの中で使う方法をメモします。

!FindInMapを!Subの中で使う

下記のようにして、!FindInMapで取得した値を!Subで代入できます。

Mappings:
  LogGroupMapping:
    Test:
      Name: test_log_group
    Prod:
      Name: prod_log_group

Resources:
  myLogGroup:
    Type: 'AWS::Logs::LogGroup'
    Properties:
      LogGroupName: !Sub 
        - 'cloud_watch_${log_group_name}'
        - log_group_name: !FindInMap [ LogGroupMapping, Test, Name ]
# ${log_group_name} が!FindInMap結果で置換される

!Subは単純に文字列内の${...}を置換する以外にも、リストの第一要素内の${...}第二要素で置換する使い方ができます。

これを利用して、!Subのリスト第二要素に!FindInMapを定義すれば、これらを併用することができます。

該当部抜粋:

LogGroupName: !Sub 
  - 'cloud_watch_${log_group_name}'
  - log_group_name: !FindInMap [ LogGroupMapping, Test, Name ]
# ${log_group_name} が!FindInMap結果で置換される

おわりに

今回はCloudFormationで!FindInMap!Sub内で使う方法をまとめました。

CloudFormationはTerraform等ほかのIaCツールより癖のある書き方を強いられることも多いですが、AWSを使う以上は避けて通れないものだと思っています。

上手いこと使いこなしていきたいものです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work

参考

Use the Fn::Sub function in AWS CloudFormation

aws-cloudformation-templates/FindInMap_Inside_Sub.yaml at master · awslabs/aws-cloudformation-templates · GitHub

amazon web services - How to use !FindInMap in !Sub | userdata section - Stack Overflow

Fn::FindInMap - AWS CloudFormation

Mappings - AWS CloudFormation

Fn::Sub - AWS CloudFormation