【AWS】AWS CloudFormation ~ 組み込み関数 ~

■ はじめに

https://dk521123.hatenablog.com/entry/2021/10/26/224812
https://dk521123.hatenablog.com/entry/2021/12/01/170326

の続き。

AWS CloudFormation (CFn) で、大体な仕組みは理解できたのだが
サンプルをみていて、組み込み関数なるものがでてきたので
よく使いそうなものをピックアップしてメモしておく。

目次

【0】組み込み関数・仕様
【1】Ref
【2】Fn::Sub
【3】Fn::GetAtt
【4】Fn::ImportValue
【5】Fn::FindInMap
【6】条件関数
 1)Fn::Equals
 2)Fn::If
 3)Fn::Or

【0】組み込み関数・仕様

* 以下の公式サイトから参照。

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

【1】Ref

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

* 指定したパラメータまたはリソース値を返却

構文

# 完全名関数の構文
Ref: <logicalName>

# 短縮形の構文
!Ref <logicalName>

サンプル

Parameters:
  EnvironmentType:
    Description: Enter environment type
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - stage
      - prod
...
Name: !Ref EnvironmentType

【2】Fn::Sub

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

* 文字列内に変数をいれる
 => 変数と文字列を結合する際に使用

構文

# 完全名関数の構文
Fn::Sub:
  - String
  - Var1Name: Var1Value
    Var2Name: Var2Value

# 短縮形の構文
!Sub
  - String
  - Var1Name: Var1Value
    Var2Name: Var2Value

# 完全名関数の構文
Fn::Sub: String

# 短縮形の構文
!Sub String

サンプル

Name: !Sub
  - www.${Domain}
  - { Domain: !Ref DomainName }

BucketName: !Sub data-${AWS::Region}-${EnviromentType}-source

参考文献
https://chariosan.com/2019/08/11/cfn_fnsub/

【3】Fn::GetAtt

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

* テンプレートのリソースから属性値を返却
 => リソースで生成した値(例:ARNなど)を取得したい場合に使用

構文

# 完全名関数の構文
Fn::GetAtt: [ <logicalNameOfResource>, <attributeName> ]

# 短縮形の構文
!GetAtt <logicalNameOfResource>.<attributeName>

サンプル

Resources:
  # IAMRole
  CodePipelineServiceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: CodeBuildServiceIamRole
...
  # CodePipeline
  CodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: CodePipeline
      RoleArn: !GetAtt CodePipelineServiceRole.Arn

参考文献
https://dev.classmethod.jp/articles/cloudformation-tempate-reference-intrinsic-function/#getatt

【4】Fn::ImportValue

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

* 別のスタックによってエクスポートされた出力値を返却

構文

# 完全名関数の構文
Fn::ImportValue: sharedValueToImport

# 短縮形の構文
!ImportValue sharedValueToImport

使用上の注意

* !ImportValue が含まれている場合、!Sub の短縮形を使用することはできない
 => 代わりに、完全な関数名を使用する必要がある

サンプル

# OK
Fn::ImportValue:
  !Sub "${NetworkStack}-SubnetID"

# NG
# !ImportValue
#  !Sub "${NetworkStack}-SubnetID" 

【5】Fn::FindInMap

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

* Mappings セクションで宣言されたマップのキーに対応する値を返却

構文

# 完全名関数の構文
Fn::FindInMap: [ MapName, TopLevelKey, SecondLevelKey ]

# 短縮形の構文
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]

# MapName : Mappings セクションで宣言された、キーと値を含むマッピングの論理名。
# TopLevelKey : 最上位のキー名。この値は、キーと値のペアのリストです。
# SecondLevelKey : 2 番目のレベルのキー名で、
#  TopLevelKey に割り当てられたリストのキーの 1 つに設定されます。

サンプル

Mappings: 
  EnvMap: 
    dev: 
      Ec2InstanceType: t2.micro
    stage: 
      Ec2InstanceType: t2.medium
    prod: 
      Ec2InstanceType: t2.large
Resources: 
  MyEC2Instance: 
    Type: "AWS::EC2::Instance"
    Properties: 
      InstanceType: !FindInMap
        - EnvMap
        - !Ref EnvironmentType
        - Ec2InstanceType

【6】条件関数

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

* 条件付きでスタックリソースを作成

1)Fn::Equals

* 2 つの値が等しいかどうかを比較

構文

# 完全名関数の構文
Fn::Equals: [value_1, value_2]

# 短縮形の構文
!Equals [value_1, value_2]

サンプル

IsProdCondition:
  !Equals [!Ref EnvironmentType, prod]

2)Fn::If

* 指定された条件が true に評価された場合は 1 つの値を返却
* 指定された条件が false に評価された場合はもう 1 つの値を返却

構文

# 完全名関数の構文
Fn::If: [condition_name, value_if_true, value_if_false]

# 短縮形の構文
!If [condition_name, value_if_true, value_if_false]

サンプル
https://stackoverflow.com/questions/41752007/conditionally-create-codepipeline-actions-based-on-cloudformation-conditions

- !If
  - IsProdCondition
  - InputArtifacts: []
    Name: !Join ["",[!Ref GitHubRepository, "-prd-approval"]]
    ActionTypeId:
      Category: Approval
      Owner: AWS
      Version: '1'
      Provider: Manual
    OutputArtifacts: []
    Configuration:
      NotificationArn: !GetAtt ["SNSApprovalNotification", "Outputs.SNSTopicArn"]
      ExternalEntityLink: OutputTestUrl
    RunOrder: 3
  - !Ref AWS::NoValue

補足:AWS::NoValue

* 以下の関連記事を参照のこと。

https://dk521123.hatenablog.com/entry/2021/12/05/134313

3)Fn::Or

* 指定された条件のいずれかが true に評価された場合は true を返却

構文

# 完全名関数の構文
Fn::Or: [condition, ...]

# 短縮形の構文
!Or [condition, ...]

サンプル

# EnviromentType が、stage or prod だった場合、MyOrCondition に true
MyOrCondition:
  !Or [!Equals [stage, !Ref EnviromentType], !Equals [prod, !Ref EnviromentType]]

関連記事

AWS CloudFormation ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2021/10/26/224812
AWS CloudFormation ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2021/12/01/170326
AWS CloudFormation ~ 疑似パラメータ ~
https://dk521123.hatenablog.com/entry/2021/12/05/134313
AWS CloudFormation ~ DeletionPolicy 属性 ~
https://dk521123.hatenablog.com/entry/2021/12/27/211328
AWS CloudFormation ~ 認証情報の扱い ~
https://dk521123.hatenablog.com/entry/2021/12/28/224501
CloudFormation で Github/CodePipeline/CodeBuild を構築する
https://dk521123.hatenablog.com/entry/2021/12/26/155956