備忘録：CFnの組み込み関数まとめ

# 内容

CFnの組み込み関数をサンプルを使用して解説します。

# サンプルテンプレート1

```yaml
Resources:
  TestVpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.0.0.0/16"
  TestSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Select [ 0, !Cidr [ !GetAtt TestVpc.CidrBlock, 1, 8 ]]
      VpcId: !Ref TestVpc
      AvailabilityZone:
        !Select [1, Fn::GetAZs: ""]
      Tags:
        - Key: Name
          Value: !Join [":",[test,subnet]]
Outputs:
  TestSubnetId:
    Value: !Ref TestSubnet
    Export:
      Name: TestSubnetId
```

### Fn::GetAtt
テンプレートのリソースから属性の値を返す。
```!GetAtt TestVpc.CidrBlock```は```"10.0.0.0/16"```を返す。

### Fn::Cidr
Cidrブロックの配列を返す。
```!Cidr [ !GetAtt TestVpc.CidrBlock, 1, 8 ]```は```TestVpc.CidrBlock="10.0.0.0/16"```から```1```つのCidrをサブネットビット数```8(/24)```で返す。

### Fn::Select
インデックスによってオブジェクトのリストから1つのオブジェクトを返す。
```!Select [ 0, !Cidr [ !GetAtt TestVpc.CidrBlock, 1, 8 ]]```は```!Cidr [ !GetAtt TestVpc.CidrBlock, 1, 8 ]=10.0.0.0/24```から```0```番目のオブジェクト```10.0.0.0/24```を返す。

### Fn::GetAZs
指定したリージョンのアベイラビリティーゾーンをアルファベット順にリストした配列を返す。
```!Select [1, Fn::GetAZs: ""]```
```Fn::GetAZs: ""```の箇所で```ap-northeast-1a``` ```ap-northeast-1c``` ```ap-northeast-1d```が返る。
```!Select [1, "ap-northeast-1a","ap-northeast-1c","ap-northeast-1d"]```となり、```1```で指定した2つ目の```ap-northeast-1c``` が返る。（インデックスは0からスタート）

### Fn::Join
区切り文字で区切って 1 つの値に追加する。
```Value: !Join [":",[test,subnet]]```では```test:subnet```が```Value```の値として返る。

### Ref
指定したパラメータまたはリソースの値を返す。
```Value: !Ref TestSubnet```ではTestSubnetで作成されたSubnet IDの値を返す


#  サンプルテンプレート2

```yaml
Mappings:
  RegionMap:
    ap-northeast-1:
      AMI: "ami-072bfb8ae2c884cc4"
    ap-northeast-3:
      AMI: "ami-0e0cbf0f03ba99ee7"

Parameters:
  EnvType:
    Description: Environment type.
    Default: dev
    Type: String
    AllowedValues: [prod,dev,test]
    ConstraintDescription: must specify prod, dev, test.
  InstanceName:
    Type: String
    Description: Enter a Instance Name

Conditions:
  CreateProdResources: !Equals [!Ref EnvType, prod]
  CreateDevResources: !Equals [!Ref EnvType, dev]

Resources:
  EC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
      InstanceType: !If [CreateProdResources, t2.small, !If [CreateDevResources, t2.micro, t2.nano]]
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !ImportValue TestSubnetId
      Tags:
        - Key: Name
          Value: !Sub ${InstanceName}
```

### !FindInMap
Mappingsセクションで宣言された 2 つのレベルのマッピングのキーに対応する値を返す。
```AWS::Region```は現在のリージョンを返すので東京リージョンであれば```ap-northeast-1```が返る。
```!FindInMap [RegionMap, ap-northeast-1, AMI]```となり、Mappingsセクションの```ami-072bfb8ae2c884cc4```が返る。

### !If
Trueの場合1つ目が、Falseの場合2つ目の値が返る。
Conditionsで```CreateProdResources```が指定された場合```!If [CreateProdResources, t2.small, !If [CreateDevResources, t2.micro, t2.nano]]```では```t2.small```が返る。
その他の場合は```!If [CreateDevResources, t2.micro, t2.nano]```が評価される。

### Fn::ImportValue
OutputsセクションでExportした値を返す。
サンプルテンプレート1のOutputsセクションでExportした```TestSubnetId```を```SubnetId: !ImportValue TestSubnetId```の箇所で参照している。

### Fn::Sub
値を代入する。
```Value: !Sub ${InstanceName}```の箇所ではParametersセクションで入力した値を受け取ってインスタンス名を設定する。

# 組み込み関数一覧

下記公式ドキュメント参照

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