Ccmmutty logo
Commutty IT
0 pv6 min read

【CloudFormation】ref,sub,getattの使い方

https://cdn.magicode.io/media/notebox/fe57671e-b25b-49b3-8d6b-217647ba8da0.jpeg

概要

こんにちは。POStaroです。
皆さんはAWS Cloudformaitonの組み込み関数のRef、Fn::Sub、Fn::GetAttを上手く使い分けできていますか?
テンプレートを書いていると、「値を参照するためにRefとFn::GetAttどちらを使えばいいかわからない」ことや「このリソースではFn:GetAttで取得できる値がわからない」ことがあるかと思います。
本記事では上記のような悩みを解決するために、CloudFormationのFn::GetAtt、Fn::Sub、Refの使い方についてまとめていこうと思います。

組み込み関数Ref、Fn::Sub、Fn::GetAttの使い方

Ref

組み込み関数Refは2つの使い方があります。※!RefはRefの短縮形で一般的にこれを使います。
  • Parametersセクションで指定したパラメータの参照
  • Resourcesセクションで指定したリソースの参照
公式ドキュメント:Ref
例1:InstanceTypeパラメータの値を取得
Parametersセクションで「InstanceType」を定義し、ユーザが入力した「InstanceType」の値をResourcesセクションでRefを用いて参照しています。
Parameters:
  InstanceType:
    Description: "EC2 instance type"
    Type: String
    Default: t2.micro   

Resources:
  MyEC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: !Ref InstanceType
      ImageId: "ami-0ff8a91507f77f867"
例2:MyS3Bucketを参照して、バケット名を取得
Resourceセクションの「MyS3Bucket」をRefで参照することで、バケット名を取得できます。
Resources:
  MyS3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: "my-bucket"

Outputs:
  BucketName:
    Value: !Ref MyS3Bucket
    Description: "Name of the S3 bucket"

Refを使用する際の注意点

下表のようにRefで返される値はリソースによって異なります。
取得したい値が返されるか、公式ドキュメントで毎回確認が必要です。
Refが使えないリソースは後述のFn::GetAttで属性を指定して取得する必要があります。
リソースRefの戻り値戻り値の例
VPC(AWS::EC2::VPC)VPC IDvpc-1a2b3c4d
IAMロール(AWS::IAM::Role)ロール名my-iam-role-name
EC2(AWS::EC2::Instance)インスタンスIDi-1234567890abcdef0
S3バケット(AWS::S3::Bucket)バケット名my-bucket-name

Fn::Sub

Refの使い方は、下記2点だと説明しました。
  • Parametersセクションで指定したパラメータの参照
  • Resourcesセクションで指定したリソースの参照
Refとの違いは上記の参照を入力文字列内で行える点にあります。また、Subで参照する場合、${}で値を囲む必要があります。
※!SubはFn::Subの短縮形です。
公式ドキュメント:Fn::Sub
例1:S3バケットを作成する環境名を参照
パラメータとしてユーザが入力した「Enviroment」を「BucketName」の文字列内でSubを用いて参照しています。
Parameters:
  Environment:
    Description: "デプロイ環境"
    Type: String
    Default: "dev"

Resources:
  MyBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "my-${Environment}-bucket"
例2:S3バケット名を参照
Resourceセクションの「MyBucket」のバケット名を「MyBucketPolicy」の文字列内でSubを用いて参照しています。
Resources:
  MyBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: "my-bucket"

  MyBucketPolicy:
    Type: "AWS::S3::BucketPolicy"
    Properties:
      Bucket: !Ref MyBucket
      PolicyDocument:
        Statement:
          - Action: "s3:GetObject"
            Effect: "Allow"
            Resource: !Sub "arn:aws:s3:::${MyBucket}/*"
            Principal: "*"

Subを使用する際の注意点

Refと同様にSubで返される値はリソースによって異なります。
取得したい値が返されるか、公式ドキュメントで毎回確認が必要です。
※RefとSubで返される値は同じため、Refの戻り値で確認してください。

Fn::GetAtt

Fn::GetAttはリソースの属性を参照する時に使用します。 「!GetAtt プロパティ名.属性」の形で使用します。
※!GetAttは短縮形です。
例:GetAttでIAMロールのArnを参照
「MyIAMRole」のArnをGetAttで参照しています。
Refで参照した場合、ロール名が返ってくるため、Arnを取得したい場合、GetAttが必要です。
Resources:
  MyIAMRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "ec2.amazonaws.com"
            Action: "sts:AssumeRole"
Outputs:
  MyIAMRoleARN:
    Description: "The ARN of the IAM role"
    Value: !GetAtt MyIAMRole.Arn

Fn::GetAtt使用する際の注意点

Refと同様に返される値は、リソースによって異なります。
取得したい値が返されるか、公式ドキュメントで確認が必要です。
リソース属性戻り値
EC2( AWS::EC2::Instance).AvailabilityZoneインスタンスが作成されたアベイラビリティゾーン
IAMロール(AWS::IAM::Role).ArnIAMロールのARN
Lambda関数(AWS::Lambda::Function).NameLambda関数の名前
RDSインスタンス(AWS::RDS::DBInstance).Endpoint.Addressデータベースインスタンスのエンドポイントアドレス

Discussion

コメントにはログインが必要です。