LoginSignup
5
3

More than 1 year has passed since last update.

【CloudFormation】組み込み関数Fn::Subが意外と便利な件

Posted at

はじめに

ちょっとした Tips ですが、意外と知らない方が多い(?)ようなので、投稿しておきます。
CloudFormation の組み込み関数 !Sub は、 !Ref!GetAtt など、他の組み込み関数の代わりとしても使用することができます。

!Ref の代わりとして使える

!Ref Resource!Sub ${Resource} は同義です。
ただし、!Ref の方が ${} が不要な分、シンプルなので、単体ではあえて !Sub を使うメリットはありません。

!Ref の場合
Parameters:
  BucketName:
    Type: String

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName

Outputs:
  SampleBucketName:
    Value: !Ref SampleBucket
!Sub の場合
Parameters:
  BucketName:
    Type: String

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${BucketName}

Outputs:
  SampleBucketName:
    Value: !Sub ${SampleBucket}

!Join の代わりとして使える

!Sub が有用なのはこのケースです。
以下のように、ARN を !Join で結合している記法を割と見かけますが、!Sub を使うと、一行でシンプルに書けて可読性も良くなります。

!Join の場合
SampleBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref SmapleBucket
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - s3:GetObject
          Principal: "*"
          Resource:
            - !Join
              - ""
              - - arn:aws:s3:::
                - !Ref SmapleBucket
                - /*
!Sub の場合
SampleBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref SmapleBucket
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - s3:GetObject
          Principal: "*"
          Resource:
            - !Sub arn:aws:s3:::${SmapleBucket}/*

!GetAtt の代わりとして使える

!GetAtt Resource.Attribute!Sub ${Resource.Attribute} は同義です。
これも !Ref と同様で、単体で使うメリットはありませんが、文字列結合が必要な場合などに有用です。

!GetAtt の場合
SampleBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref SmapleBucket
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - s3:GetObject
          Principal: "*"
          Resource:
            - !Join
              - ""
              - - !GetAtt SmapleBucket.Arn
                - /*
!Sub の場合
SampleBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref SmapleBucket
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - s3:GetObject
          Principal: "*"
          Resource:
            - !Sub ${SmapleBucket.Arn}/*

リファレンス

これらの仕様は CloudFormation ユーザーガイドにも明記されています。

テンプレートパラメータ名、または ${InstanceTypeParameter} などのリソースの論理 ID を指定すると、CloudFormation は Ref 組み込み関数を使用した場合と同じ値を返します。
${MyInstance.PublicIp} などのリソース属性を指定すると、CloudFormation は Fn::GetAtt 組み込み関数を使用した場合と同じ値を返します。

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

おわりに

簡単な Tips でしたが、本記事を書こうと思ったのは、

  Resource:
    - !Join
      - ""
      - - arn:aws:s3:::
        - !Ref SmapleBucket
        - /*

のような記法を意外とよく見かけることがあり、「!Sub を使えば一行で書けるのに…」と思ったことがきっかけでした。

この記法をよく見かけるのはおそらく、AWS の公式ドキュメントにおいても、この記法が使われているためではないかと推測しています。
例えば、以下の Examples など。

CloudFormation テンプレートでも、プログラムでも、シンプルに書けるのであれば、シンプルに書いたほうがよいと思います。

最後まで読んでいただき、ありがとうございます。
本記事が少しでも役に立てば幸いです。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3