目的
AWS初心者の方でドキュメントの見方が分からない為、色々なブログに書いてある抜粋されたテンプレートを参考にしながら書いている方向けに
AWSの公式ドキュメントを参考にしながら、CloudFormationのテンプレートを書けるようになることが、今回の目的です。
今回はyamlで書きますが、jsonでもドキュメントの見方は変わらないです。
テンプレートの構成要素
AWSTemplateFormatVersion: 2010-09-09
Description: ---
Metadata:
Parameters:
Mappings:
Conditions:
Resources:
Outputs:
- AWSTemplateFormatVersion
テンプレートのフォーマットバージョンを指定します。
現在の最新は公式ページを見ることで確認できます。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/format-version-structure.html - Metadata
テンプレートの付加情報を記述します。
コンソールから見た時のパラメータの順番などもここで制御できます。 - Parameters
スタックを作成する時に値を指定したい場合などに、パラメータとして受け取ります。
受け取った値をResourcesで宣言するリソースの設定値に指定することも可能です。 - Mappings
キーと値をマッピングすることができます。
キーがxxxの場合は値はyyyである。のように紐づけた管理表のようなものを記述することができます。 - Description
テンプレートの説明を記述します。 - Conditions
IF分岐をする場合などに使用します。
入力パラメータで受け取った値がxxxならtrueを返し、yyyならfalseを返却する等の条件を記述します。 - Resources
AWSリソースを宣言する本文です。
作成したいAWSサービスのプロパティに沿って記述します。 - Outputs
スタック外にリソースの情報をアウトプットします。
Aスタックで宣言しているリソースのIDをBスタックで使用したい場合などに使用します。
この中で必須の要素がAWSTemplateFormatVersionとResourcesになります。
その他はオプションとして、必要な時に使用します。
Parametersは良く使用すると思うので、今回は必須要素とParametersを使用して説明していきます。
テンプレートの作成
今回は例として、EC2とそれにアタッチするSecurityGroupを作成するテンプレートを作成したいと思います。
EC2
まず作成したいAWSサービスで何が設定できるのかを調べます。
※CloudFormation 「サービス名」とかで検索できます。
検索するとこのような公式ドキュメントがヒットすると思います。
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html
Type:は何のリソースかを表しています。(今回は大枠がEC2で、その中のInstanceです。)
Properties:配下がEC2で指定できるプロパティです。
それぞれ説明があるので、必要に応じて使用します。
※必須プロパティもあるので、注意してください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
ImageId:
Type: AWS::EC2::Image::Id
IamRole:
Type: String
VpcId:
Type: String
SubnetId:
Type: String
VolumeSize:
Type: Number
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: "t2.micro"
IamInstanceProfile: !Ref IamRole
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroup
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: !Ref VolumeSize
VolumeType: gp3
DeleteOnTermination: true
Encrypted: false
Tags:
- Key: Name
Value: my-instance
今回は、これらを設定して作成したいと思います。
Parameters
AMI、インスタンスにアタッチするIAMロール、配置VPCのID、配置サブネットのID、EBSのサイズをスタック作成時に指定できるように記述します。
Resources
下記4つはParametersで受け取った値を組み込み関数の1つであるRef関数※1を使用して取得しています。
- ImageId
- IamInstanceProfile
- SubnetId
- VolumeSize
- SecurityGroupIds
あとで作成するセキュリティグループのIDをRef関数※1で取得して設定しています。
ドキュメントを確認すると 「- String」となっています。こちらは文字列配列を指定することを意味します。
今回は1つしか指定していませんが、複数のSecurityGroupIdを指定する場合は、下記のように書きます。
SecurityGroupIds:
- SecurityGroupId1
- SecurityGroupId2
jsonだとこうなります。
"SecurityGroupIds":["SecurityGroupId1","SecurityGroupId2"]
- BlockDeviceMappings
ドキュメントを確認すると「- BlockDeviceMapping」となっています。
こちらは「BlockDeviceMapping」の配列を指定することを意味します。
設定値については、BlockDeviceMappingをクリックすることで確認することができます。
Ebs:の箇所は配列ではなく、EbsというKeyに対して、複数のkey:valueを指定します。
「-」はつけずに、インデント(先頭の空白)をつけて記述していきます。
BlockDeviceMappingsは配列指定なので、こちらも複数指定することが可能です。
その場合は、このようにBlockDeviceMappingの要素を複数記述することになります。
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: !Ref VolumeSize
VolumeType: gp3
DeleteOnTermination: true
Encrypted: false
- DeviceName: /dev/xvdb
Ebs:
VolumeSize: 8
VolumeType: gp3
DeleteOnTermination: true
Encrypted: false
- Tags
BlockDeviceMappingsと同じ要領でTagの要素を記述していきます。
※1
Ref関数は、基本的に宣言している論理名を引数として渡すと対応した値を取得することができます。
取得できる値はサービスによって変わりますが、それぞれのドキュメントの「Return values」を確認することで何が取得できるのかがわかります。
例えば、今回のSecurityGroupの場合だと、「resource ID」とあるので、SecurityGroupのIDを取得できることがわかります。
Parametersの論理名を指定した場合は、パラメータの値を取得します。
SecurityGroup
EC2でSecurityGroupを使用しているので、同じ要領で、
EC2.ymlにSecurityGroupの記述を追加します。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
ImageId:
Type: AWS::EC2::Image::Id
IamRole:
Type: String
VpcId:
Type: String
SubnetId:
Type: String
VolumeSize:
Type: Number
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: "t2.micro"
IamInstanceProfile: !Ref IamRole
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroup
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: !Ref VolumeSize
VolumeType: gp3
DeleteOnTermination: true
Encrypted: false
Tags:
- Key: Name
Value: my-instance
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: "my-sg"
SecurityGroupEgress:
- CidrIp: "0.0.0.0/0"
FromPort: -1
ToPort: -1
IpProtocol: "-1"
SecurityGroupIngress:
- CidrIp: "0.0.0.0/0"
Description: "https"
FromPort: 443
ToPort: 443
IpProtocol: "tcp"
Tags:
- Key: "Name"
Value: "my-sg"
VpcId: !Ref VpcId
今回は
アウトバウンド:すべて
インバウンド:httpsのみ許可
で作成しています。
まとめ
ドキュメントを参考にする際には下記を気をつける。
- 設定可能なプロパティを確認する。
- 入れ子になっている要素はリンクを踏む。
- 配列なのかを確認する。
- Refで何が取得できるのかを確認する。
最後に
CloudFormationはとても面白いサービスです。
今回はRef関数のみ、組み込み関数を使用しましたが、他にもSubや、GetAtt、Split、Joinなどさまざまな関数が用意されています。
また、カスタムリソースを使用して、CloudFormationではサポートされていない挙動を外部でLambda関数として定義しておいて、スタックの作成、更新、削除のタイミングでLambdaを起動する等も可能です。
気になる方は調べてみることをお勧めします。