AWS CloudFormationで!FindInMap
を!Sub
内で使うやり方をまとめます。
はじめに
こんにちは、@bioerrorlogです。
CloudFormationの!Sub
は値を代入/置換 ("substitute")できる関数、!FindInMap
はMappings
から値を取得できる関数です。
(!Sub
はFn::Sub
の短縮記法、!FindInMap
はFn::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を使う以上は避けて通れないものだと思っています。
上手いこと使いこなしていきたいものです。
[関連記事]
参考
Use the Fn::Sub function in AWS CloudFormation
amazon web services - How to use !FindInMap in !Sub | userdata section - Stack Overflow