【備忘録】組み込み関数

[組み込み関数リファレンス - AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)

:::note warn
関数の選定基準は、利用頻度や使い勝手を考慮しており、あくまで個人の見解に基づいています。使用する際の環境や要件によっては異なる場合があるため、あらかじめご了承ください。
:::




よく使う(☆特によく使う)

- [Fn::Base64](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-base64.html) ☆
- [条件関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html)
- [Fn::FindInMap](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html)
- [Fn::GetAtt](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html) ☆
- [Fn::ImportValue](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html) ☆
- [Fn::Join](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-join.html)
- [Fn::Select](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html)
- [Fn::Split](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-split.html)
- [Fn::Sub](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html) ☆
- [Fn::ToJsonString](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ToJsonString.html)
- [Ref](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) ☆

あまり使わない

- [Fn::Cidr](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html)
- [Fn::ForEach](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-foreach.html)
- [Fn::GetAZs](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html)
- [Fn::Length](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-length.html)
- [Fn::Transform](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-transform.html)

---

## Fn::Ref / Fn::Sub / Fn::GetAtt

↓前回記事にて、別途まとめています。

https://qiita.com/hakoda_fumiko/items/dd6e72c2c9f7d51ce295

## **Fn::FindInMap**

Mappings に指定しておくと、参照できる

```jsx
Mappings:
  AzMap:
    ap-northeast-1:
      1st: ap-northeast-1a
      2nd: ap-northeast-1c
      3rd: ap-northeast-1d
```

```jsx
Resources:  
  EC2Bastion:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !FindInMap [AzMap, !Ref AWS::Region, 1st]
```

[擬似パラメータ参照 - AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html)

**`AWS::NoValue`** とかもある

```jsx
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${AWS::AccountId}-${AWS::Region}-mybucket"
```

などを使いS3のバケット名の重複を防ぎます



## **Fn::Base64**

組み込み関数 `Fn::Base64` は、入力文字列の Base64 表現を返します。この関数は通常、`UserData` プロパティを介して Amazon EC2 インスタンスにエンコードされたデータを渡すために使用されます。

```jsx
UserData:
	Fn::Base64: !Sub
		#!/bin/bash
		apt-get update -y
		apt-get upgrade -y
		apt-get install nginx -y
		touch test_file
		chown ${Username}:${Username} test_file
```

## **Fn::ImportValue**

インポートの出力をし、他ファイル(vpcのIDをEC2に引っ張る)で使えるようにする。

```yaml
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCiderBlock
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-vpc
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  
  
 Outputs:
  VPC:
    Value: !Ref VPC
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-vpc
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
```

- `Outputs`セクションで`Value:`にて`!Ref VPC`使用している部分は、

実際には同じファイル内の`Resources`セクションにある`VPC`リソースを参照

- Export:
      Name: 
は指定のもの(上記ならVPC)の`NameTag`を記載する。

上記にて、準備が完了



 別ファイルで`ImportValue`を活用し使用する。
( VpcId: を丸々書くのを省略できる)

```jsx
Resources:
  SecurityGroupBastion:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub
        - ${SystemName}-${EnvType}-sg-bastion
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      GroupName: !Sub
        - ${SystemName}-${EnvType}-sg-bastion
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      VpcId: 
        Fn::ImportValue: !Sub
          - ${SystemName}-${EnvType}-vpc
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
```

`!` が連なるとエラーが出るため、`!Sub`を使用するので`Fn::ImportValue`と書く

`Outputs:` で指定している、`Name:`を記載しインポートを行う

## Fn::Join

Subとやっていることがほぼ同じ


```jsx
!Join
	- ''
	- - 'arn:aws:s3:::'
		-!Ref SystemName
		
		
# これをSubで書くと

!Sub arn:aws:s3:::${SystemName}
```
[Amazon Resource Name とは？ - Qiita](https://qiita.com/miyuki_samitani/items/4bcfa6343d710f4f9354)

AWS内のリソースを一意に識別するために使用される名前です。AWSのさまざまなリソース（例：EC2インスタンス、S3バケット、IAMユーザーなど）には、それぞれ固有のARNが付与されます。ARNは、リソースを一意に識別し、アクセス制御やリソースの参照に使用されます



# **条件関数**

## Fn::If

自分が起動しようとしているものと同じであれば、x86だというコード

```jsx
Conditions:
	isX86Architecture: !Equals [!Ref LanchAmiId, !Ref RawX86AmiId]
	
Resources:
	UserData: !If
		- isX86Architecture
		- Fn::Base64: Sub!
				#!/bin/bash
				echo x86
		- Fn::Base64: Sub!
				#!/bin/bash
				echo arm64	
```

上がtrue

下がfalse

## Fn::Not

Devと同じじゃないときtrue

```jsx
Conditions:
	isNotDev: !Not [!Equals [!Ref EnvType, dev]]
```

## Fn::And

Devで、かつ東京だったらtrue

```jsx
Conditions:
	isDevAndTokyo: !And [!Equals [!Ref EnvType, dev], !Equals [!Ref AWS::REgion, ap-northeast-1]]
```

## Fn::Or

devかstgの場合true（本番環境以外の時）

```jsx
Conditions:
	isDevOrStg:
		!Or [!Equals [!Ref EnvType, dev], !Equals [!Ref EnvType, stg]]
```



# あまり使わない

## Fn::ForEach

ループ処理ができる

```jsx
Transform:　'AWS::LanguagrExtensions'
		
Parameters:
	HogeItemNames:
		Type: List<String>
		Default: AAA, BBB, CCC
		
Resources:
	'Fn::ForEach::HogeItemName':
		- HogeItems
		- !Ref HogeItemNames
		- 'Topic${HogeItems}':
				Type: 'AWS::SNS::Topic'
				Properties:
					TopicName: !Ref HogeItems
```

## Fn::GetAZs

指定したリージョンのアベイラビリティーゾーンをアルファベット順にリストした配列を返します。

```jsx
AvailabilityZone: !Select
	- 0
	- Fn::GetAZs: !Ref 'AWS::Region'
```

これだと０番目のアベイラビリティーゾーンのことを指す

しかし、アベイラビリティーゾーンの追加削除で順が変わったりするため使い勝手が悪い。

⇒**FindInMapを使ったほうがいい**

## **Fn::Length**

数をかぞえる

```jsx
Fn::Length:
	!Split ["|", "a|b|c"]

# 3が返る
```

`Fn::Split`  …文字列を指定された区切り文字で分割します

## **Fn::ToJsonString**

指定されたオブジェクトをJSON文字列に変換

```jsx
Fn::ToJsonString:
	- key1: value1
		key2: !Ref ParameterName
		
# "[{\"key1\":\"value1\"},{\"key2\":\"resolvedValue\"}]"
```

## **Fn::Transform**

AWS側から用意されていないテンプレートを使いたいときに自分で設定し使えるようにする。

⇒あまり使い道がないと思われる

## Fn::Cider

詳細については、下記Classmethodの記事
(https://dev.classmethod.jp/articles/cidr_cloudformation/)
の「**!Cidrのパラメータと配列データの関係**」
をご参照ください。

※個人的にはこの記事がとてもわかりやすいと感じました。

⇒Ciderを指定できないのであまり使わないと思われる