あなたもできる! CloudFormationテンプレートセッションまとめ ( 2 )

2022.07.25

こんにちは、クラスメソッド イムです。
私は最初にCloudFormationテンプレートを作成する時にコードとかセッションがよく理解できず、迷っていたりしました。
なので、今回のブログではCloudFormationテンプレートを始て作成する方も理解しやすいようにCloudFormationテンプレートのセッションについてまとめたいと思います。

ブログは全部で2つに分かれています。
このブログで紹介されてないCloudFormationテンプレートのセッションについては下記のブログを参考ください。

アジェンダ

  1. Rules
  2. Mappings
  3. Conditions
  4. Transform
  5. まとめ

1. Rules

スタックを作成したりアップデートする際に、テンプレートに送信されたパラメータまたはパラメータの組み合わせを検証します。
ルールセクションは、リソースを作成、アップデートする前にパラメータ値を検証します。

ルールセッションでは、下記の関数を使用します。

  • Fn::And
  • Fn::Contains
  • Fn::EachMemberEquals
  • Fn::EachMemberIn
  • Fn::Equals
  • Fn::If
  • Fn::Not
  • Fn::Or
  • Fn::RefAll
  • Fn::ValueOf
  • Fn::ValueOfAll

rules-test.yaml

AWSTemplateFormatVersion: '2010-09-09'

Rules:
  devInstanceType:
    RuleCondition: !Equals 
      - !Ref Environment
      - dev
    Assertions:
      - Assert:
          'Fn::Contains':
            - - t2.medium
            - !Ref InstanceType
        AssertDescription: 'instance type must be t2.medium'
  prdInstanceType:
    RuleCondition: !Equals 
      - !Ref Environment
      - prd
    Assertions:
      - Assert:
          'Fn::Contains':
            - - t2.large
            - !Ref InstanceType
        AssertDescription: 'instance type must be t2.large'

...

上記の例は2つのインスタンスタイプで定義されたパラメータ値を検証します。
つまり、dev インスタンスは t2.medium で、prd インスタンスは t2.large であることを確認します。

2. Mappings

Mappings セッションでは、キーと名前付きの一連の値をセットで定義します。
例えば、リージョン名をキーとしてリージョンごとに必要な値を指定して使用します。
また、Mappings セッション定義した値を取得するためには Fn::FindInMap 関数を使用します。

mappings-test.yaml

AWSTemplateFormatVersion: "2010-09-09"

# ------------
# Mappings
# ------------
Mappings: 
  RegionMap: 
    us-east-1:
      HVM64: ami-0fxxxxxxxxxxxxx54
    us-east-2:
      HVM64: ami-0bxxxxxxxxxxxxx34
    ap-northeast-1:
      HVM64: ami-06xxxxxxxxxxxxx32
    ap-northeast-2:
      HVM64: ami-08xxxxxxxxxxxxx51

# ------------
# Resources
# ------------
Resources: 
  EC2Instance: 
    Type: "AWS::EC2::Instance"
    Properties: 
      ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", HVM64]
      ...

上記の Mappings セッションではリージョン名をキーとして、AMIの値を定義しました。
そして、リソースで使用する時は、例の24行のように作成します。

上記コードの意味は以下となります。
1) Mappings セッションの中で RegionMap というグループの中に
2) Cfn を実行するリージョンと同じ値の
3) HVM64に定義されている値を取得する。

3. Conditions

条件 (Conditions) セッションでは、条件関数を通じてリソース作成または構成された環境を定義する文が含まれます。
例えば、条件を作成して条件が true の場合、AWS CloudFormation でリソースまた作成は出力ができます。
また、条件をプロパティに関連付けて条件が true の場合、AWS CloudFormation でプロパティを特定の値に設定、falseの場合には AWS CloudFormation は他の値で設定されます。

条件 (Conditions)作成のためには下記の関数を使用します。

  • Fn::And
  • Fn::Equals
  • Fn::If
  • Fn::Not
  • Fn::Or

conditions-test.yaml

AWSTemplateFormatVersion: '2010-09-09'

# ------------
# Conditions
# ------------
Conditions:
    isAccount: !Equals [!Ref "AWS::AccountId", 67xxxxxxxxxx]
 
# ------------
# Resources
# ------------
Resources:
    vpc:
        Type: AWS::ec2::VPC
        Properties:
            CidrBlock: 10.0.0.0/16
            EnableDnsHostnames: true
            EnableDnsSupport: true
            Tags:
                - Key: Name
                  Value: !Sub Conditions-vpc
        Condtion: isAccount

上記の例はアカウントIDが Cfnを実行するアカウントIDと一致する時、リソースを作成します。

4. Transform

トランスフォーム(Transform) セッションは AWS CloudFormation がテンプレート処理のために使用するマクロを1つ以上指定します。
AWS CloudFormation では指定された順番によってマクロを実行します。

transform-test.yaml

AWSTemplateFormatVersion: '2010-09-09'
  
# Transform for Description
Fn::Transform:
	Name: AWS::Include
	Parameters:
		Location: description.yaml
  
# ------------
# Resources
# ------------
Resources:
	# Transform for Resources
	Fn::Transform:
		Name: AWS::Include
		Parameters:
			Location: bucket1.yaml
  
	Bucket2:
		Type: AWS::S3::Bucket
		Properties:
			BucketName: !Sub  Backet2-${AWS::AccountId}
			# Transform for tags
			Fn::Transform:
				Name: AWS::Include
				Parameters:
					Location: tags.yaml

次に、transform-test.yaml ファイルの TransformLocation にファイル名を入力します。

description.yaml

Description: 'Test Transform'

bucket1.yaml

Backet1:
	Type: AWS::S3::Bucket
	Properties:
		BucketName: !Sub  Backet1-${AWS::AccountId}
		AccessControl: Private
		PublicAccessBlockConfiguration:
		BlockPublicAcls: True
		BlockPublicPolicy: True
		IgnorePublicAcls: True
		RestrictPublicBuckets: True
	Tags:
		- Key: Name
		  Value: Bucket1

tags.yaml

Tags:
	- Key: Name
	  Value: Bucket2

すると、テンプレートをパッケージ化した時、下記のように変更されます。

package.yaml

AWSTemplateFormatVersion: '2010-09-09'
Fn::Transform:
	Name: AWS::Include
	Parameters:
		Location: s3://<S3name>/5011e6xxxxxxxxxxxxxxxxxxxxxxxxx
Resources:
	Fn::Transform:
		Name: AWS::Include
		Parameters:
			Location: s3://<S3name>/4fbdc0xxxxxxxxxxxxxxxxxxxxxxxxx
	Bucket2:
		Type: AWS::S3::Bucket
		Properties:
			BucketName: !Sub  Backet2-${AWS::AccountId}
			Fn::Transform:
				Name: AWS::Include
				Parameters:
					Location: s3://<S3name>/b7b7a3xxxxxxxxxxxxxxxxxxxxxxxxx

5. まとめ

今回のブログでは、CloudFormationテンプレートのセッションについてまとめてみました。