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

2022.07.25

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

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

アジェンダ

  1. サンプルテンプレート
  2. その他
  3. Parameters
  4. Metadata
  5. Resources
  6. Outputs
  7. まとめ

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

今回のブログでテンプレートセッションを勉強するために使うテンプレートです。

sample.yaml

AWSTemplateFormatVersion: "2010-09-09"
Description: "CloudFormation Simple Template"
  
# ------------
# Metadata
# ------------
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Naming setting for Tags
        Parameters:
          - System
          - Env
  
# ------------
# Parameters
# ------------
Parameters:
	System:
		Description: "System prefix of each resource names."
		Type: String
		Default: "system"
	Env:
		Description: "Environment"
		Type: String
		Default: "dev"
	EC2KeyName:
		Description: "EC2 key pair name"
		Default: "ec2-key"
		Type: String
	EC2InstanceType:
		Description: "EC2 instance type"
		Default: "r5a.xlarge"
		Type: String
	AMI:
		Description: "Server AMI"
		Default: "ami-00aea8c45ad3c4df0"
		Type: String
  
# ------------
# Resources
# ------------
Resources:
	# ------------
	# EC2 Instance
	# ------------
	EC2Instance:
		Type: AWS::EC2::Instance
		Properties:
			ImageId: !Ref  AMI
			InstanceType: !Ref  EC2InstanceType
			KeyName: !Ref  EC2KeyName
			DisableApiTermination: True
			EbsOptimized: True
			BlockDeviceMappings:
				- DeviceName: /dev/sda1
					Ebs:
						VolumeSize: 150
						VolumeType: gp2
			SecurityGroupIds:
				- !Ref  SecurityGroup
			SubnetId: subnet-0a1b785ebede2e3aa
			Tags:
				- Key: Name
					Value:
						Fn::Sub: "${System}-${Env}-ec2"
	  
	# ------------
	# SecurityGroup
	# ------------
	SecurityGroup:
		Type: AWS::EC2::SecurityGroup
		Properties:
			GroupName:
				Fn::Sub: "${System}-${Env}-sg"
			GroupDescription:
				Fn::Sub: "${System}-${Env}-sg"
			VpcId: vpc-db8475bd
			SecurityGroupIngress:
				- IpProtocol: tcp
					FromPort: 3389
					ToPort: 3389
					CidrIp: 10.0.0.0/8
			Tags:
				- Key: Name
					Value:
						Fn::Sub: "${System}-${Env}-sg"
  
# ------------
# Outputs
# ------------
Outputs:
	EC2Instance:
		Value: !Ref  EC2Instance
		Description: EC2 instance
		Export:
			Name: EC2Instance

このテンプレートはEC2, SecurityGroupを作成します。

2. その他

テンプレートの一番上にある2つのコードからまとめてみましょう。

形式バージョン

AWSTemplateFormatVersion: "2010-09-09"

テンプレートの機能を識別するフォーマットバージョンで、最新バージョンは2010-09-09です。
コードを作成するには大きな意味がないコードです。
習慣のように一番上に作成して始めましょう。

Description (説明)

Description: "CloudFormation Simple Template"

テンプレートの説明になります。
実際に作成されたスタックで確認をすると、下記のような写真みたいに表示されます。

3. Parameters

次に Parameters についてまとめてみましょう。

# ------------
# Parameters
# ------------
Parameters:
	System:
		Description: "System prefix of each resource names."
		Type: String
		Default: "system"
	Env:
		Description: "Environment"
		Type: String
		Default: "dev"
	EC2KeyName:
		Description: "EC2 key pair name"
		Default: "ec2-key"
		Type: String
	EC2InstanceType:
		Description: "EC2 instance type"
		Default: "r5a.xlarge"
		Type: String
	AMI:
		Description: "Server AMI"
		Default: "ami-00aea8c45ad3c4df0"
		Type: String

パラメータは以下のように定義されます。
このように定義されたパラメータは、コンソール上で写真のように確認できます。

また、Typeにリソースを指定するコードを入れて存在するリソースを選択させたり、複数のリソースを選ぶこともできます。

Parameters:
	Subnet:
		Description: "Subnet network"
		Type: List<AWS::EC2::Subnet::Id>
	SG:
		Description: "SecurityGroup"
		Type: AWS::EC2::SecurityGroup::Id

私がパラメータとして処理するものは以下のとおりです。
1) 何度も使う情報
2) テンプレートに書きたくないデリケートな情報
3) 最後まで確認したいリソース情報

ただし、リソースを指定するコードは限られているので下記の公式ページを参考にして作成しましょう。

4. Metadata

次は Metadata についてまとめてみます。
Metadata は上でまとめたパラメータと関連があります。
なぜなら、パラメータを区分してグループ化する役割をするからです。

# ------------
# Metadata
# ------------
Metadata:
	AWS::CloudFormation::Interface:
	ParameterGroups:
		- Label:
			default: Naming setting for Tags
		Parameters:
			- System
			- Env

まず、 Metadata を使用していない例と使用した例を比較してみます。

[Metadata 使用していない例]

[Metadata 使用した例]

違いが見えますか?
Metadata を使用してない場合には、パラメータがアルファベット順に表示されるため、どのパラメータなのかわかりにくいです。
なので、関連があるパラメータをまとめて見やすくする時にMetadataを使います。

5. Resources

次には Resources についてまとめてみます。
Resources は CloudFormation セッションの中で最も重要な部分です。
なぜなら、文字通り作成するリソースを定義する部分だからです。

# ------------
# Resources
# ------------
Resources:
	# ------------
	# EC2 Instance
	# ------------
	EC2Instance:
		Type: AWS::EC2::Instance
		Properties:
			ImageId: !Ref  AMI
			InstanceType: !Ref  EC2InstanceType
			KeyName: !Ref  EC2KeyName
			DisableApiTermination: True
			EbsOptimized: True
			BlockDeviceMappings:
				- DeviceName: /dev/sda1
					Ebs:
						VolumeSize: 150
						VolumeType: gp2
			SecurityGroupIds:
				- !Ref  SecurityGroup
			SubnetId: subnet-0a1b785ebede2e3aa
			Tags:
				- Key: Name
					Value:
						Fn::Sub: "${System}-${Env}-ec2"
	  
	# ------------
	# SecurityGroup
	# ------------
	SecurityGroup:
		Type: AWS::EC2::SecurityGroup
		Properties:
			GroupName:
				Fn::Sub: "${System}-${Env}-sg"
			GroupDescription:
				Fn::Sub: "${System}-${Env}-sg"
			VpcId: vpc-db8475bd
			SecurityGroupIngress:
				- IpProtocol: tcp
					FromPort: 3389
					ToPort: 3389
					CidrIp: 10.0.0.0/8
			Tags:
				- Key: Name
					Value:
						Fn::Sub: "${System}-${Env}-sg"

リソースは Type: AWS::EC2::SecurityGroupTypeに入力することで決定されます。
その後、リソース別に必須項目があり、選択項目があるので格項目を入力すればいいです。

それぞれのリソースについての項目は1つずつ説明するには量が多いので公式ページを参考にしてください。

また、初めて作成する方は最初から作成するのは難しいかもしれないので、他の人が作成したテンプレートをコピーして作成することも良いでしょう。

6. Outputs

最後に Outputs についてもまとめてみます。
Outputs は、他のスタックからリソースを取得したい時に使用します。

# ------------
# Outputs
# ------------
Outputs:
	EC2Instance:
		Value: !Ref  EC2Instance
		Description: EC2 instance
		Export:
			Name: EC2Instance

上記のコードで説明すると、リソースで定義しておいたEC2インスタンスの値を出力することです。
コンソール画面で見ると、より簡単に理解できます。

コンソール画面では、Outputs で定義して出力された値を表で確認できます。
上記コードで定義したEC2インスタンスの出力値は、
エクスポート名 : 他のスタックで使用する際に使用されるキー
: 他のスタックで使用すると適用される値
と理解できます。

実際に他のスタックで使用する時は、次のように使用されます。

!ImportValue  EC2Instance

この時、使用すること(!ImportValue)を関数と言います。
関数についてもっと詳しく知りたいなら、下記のブログを参考にしてください。

7. まとめ

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