初学者向けCloudFormationテンプレートの書き方の調べ方
「CloudFormationが何かは分かった、次は自分が作りたいものを自分で書いてみよう!」という人のための記事です。
公式ドキュメントで書き方を調べる
リソースの書き方を調べる
リソースタイプ(Type
)でググると、公式のCloudFormationユーザーガイドがヒットします。
例えばサブネットの書き方が知りたい場合は、「AWS::EC2::Subnet」で検索するとAWS::EC2::Subnet - AWS CloudFormationが見つかります。
実際にテンプレートを書くときは、やはりこのユーザーガイドを見ながら書いていくことになると思います[1]。
記載例を見る
ユーザーガイドの「Example」セクションを見ると、テンプレートの例を確認できます。ここで基本的な書き方をさっと知ることができます。
サブネットの場合、以下のような例が掲載されています。
mySubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
CidrBlock: 10.0.0.0/24
AvailabilityZone: "us-east-1a"
Tags:
- Key: stack
Value: production
必須プロパティを知る
プロパティ(Properties
)の中で最低限必要な項目を知るには、「Required: Yes」となっているプロパティを探します。
サブネットの場合はVpcId
の指定が必須のようです。
VpcId
The ID of the VPC the subnet is in.If you update this property, you must also update the
CidrBlock
property.Required: Yes
Type: String
Update requires: Replacement
また、「Required: Conditional」となっているプロパティも場合により必須となります。サブネットの場合、通常はCidrBlock
も必要になると思います。
これらの必須プロパティは、必ずテンプレートに記載するようにします。
プロパティの値の書き方を知る
プロパティの値の形式は、各プロパティの説明の「Type」に記載されています。
例えばTags
は「Type: Array of Tag」と記載されています。
Tags
Any tags assigned to the subnet.Required: No
Type: Array of Tag
Update requires: No interruption
「Tag」のリンクを開くと、以下の構文であることが分かります。
Key: String
Value: String
したがって、Tags
はその配列となるため、以下のようにテンプレートを書けばよいことが分かります。
Tags:
- Key: key1
Value: value1
- Key: key2
Value: value2
このようにして、リソースの各プロパティを埋めていきます。
!Ref
や!GetAtt
で得られる値を知る
他のリソースで!Ref mySubnet
のようにリソースを参照することがよくありますが、このとき返ってくる値は何でしょうか?
それは「Return values」セクションの「Ref」を見ると分かります。
サブネットの場合は「IDを返す」と説明されています。
Ref
When you pass the logical ID of this resource to the intrinsic Ref function, Ref returns the ID of the subnet.
サブネットの場合はIDを返すとすぐに分かるかもしれませんが、以下のように迷うリソースもあります。リソースタイプによって返す値はかなりバラバラであるため、参照を使用する際は都度確認が必要です。
また、同じセクションの「Fn::GetAtt」で、!GetAtt
で得られるアトリビュートも確認することができます。
例えば、サブネットでは!GetAtt mySubnet.CidrBlock
のように書くと、サブネットのIPv4 CIDRブロックの値を得られることが分かります。
!Ref
などのCloudFormation特有の表記を調べる
リソースのプロパティの書き方以外にも、CloudFormation特有の書き方のコツを知っておく必要があります。
すぐにすべてを覚える必要はありませんが、一度目を通しておくと、後で役に立つ場面があるはずです。
-
組み込み関数リファレンス:
!Ref
、!GetAtt
、!Sub
、!If
、Condition
など -
リソース属性リファレンス:
DeletionPolicy
、DependsOn
など -
擬似パラメータ参照:
AWS::AccountId
、AWS::Region
など
既存のリソースを参考にする
コンソールで作ったリソースを参考に、各プロパティの書き方を調べたい場合があると思います。
そんなときは、AWS CLIでget-*
、describe-*
、list-*
などの読み取りコマンドを実行するとよく分かります。
# サブネットのプロパティを取得できそうなコマンドを確認します。もちろんググっても良いです。
$ aws ec2 help | grep subnet
o associate-subnet-cidr-block
o create-default-subnet
o create-subnet
o create-subnet-cidr-reservation
o delete-subnet
o delete-subnet-cidr-reservation
o describe-subnets
o disassociate-subnet-cidr-block
o get-subnet-cidr-reservations
o modify-subnet-attribute
# describe-subnetsで行けそうなので実行します。
$ aws ec2 describe-subnets
{
"Subnets": [
{
"AvailabilityZone": "ap-northeast-1c",
"AvailabilityZoneId": "apne1-az1",
"AvailableIpAddressCount": 4091,
"CidrBlock": "10.0.16.0/20",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"MapCustomerOwnedIpOnLaunch": false,
"State": "available",
"SubnetId": "subnet-1234567890abcdefg",
"VpcId": "vpc-1234567890abcdefg",
"OwnerId": "123456789012",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Name",
"Value": "mysystem-subnet-public2-ap-northeast-1c"
}
],
"SubnetArn": "arn:aws:ec2:ap-northeast-1:123456789012:subnet/subnet-1234567890abcdefg",
"EnableDns64": false,
"Ipv6Native": false,
"PrivateDnsNameOptionsOnLaunch": {
"HostnameType": "ip-name",
"EnableResourceNameDnsARecord": false,
"EnableResourceNameDnsAAAARecord": false
}
},
...
これを見ると、describe-subnets
の出力はAWS::EC2::Subnet
の構文とほとんど同じであることが分かります。
Type: AWS::EC2::Subnet
Properties:
AssignIpv6AddressOnCreation: Boolean
AvailabilityZone: String
AvailabilityZoneId: String
CidrBlock: String
EnableDns64: Boolean
EnableLniAtDeviceIndex: Integer
Ipv4IpamPoolId: String
Ipv4NetmaskLength: Integer
Ipv6CidrBlock: String
Ipv6CidrBlocks:
- String
Ipv6IpamPoolId: String
Ipv6Native: Boolean
Ipv6NetmaskLength: Integer
MapPublicIpOnLaunch: Boolean
OutpostArn: String
PrivateDnsNameOptionsOnLaunch:
PrivateDnsNameOptionsOnLaunch
Tags:
- Tag
VpcId: String
よって、AWS CLIの出力と同じようにテンプレートを書けば、同じようなリソースを作成することができます。
AIに書いてもらう
最近では、まずはAIに書いてもらうのも良い手段だと思います。
ChatGPTに「○○を含むCloudFormationテンプレートをYAML形式で書いて」などと聞いてみると、説明付きでテンプレートを例示してくれて便利です。
本格的にやるなら、Visual Studio CodeにAmazon Q拡張機能をインストールしてAWS Builder IDにサインアップしてCodeWhisperer(AIコード提案機能)を使用するといった方法もあります。
書き方が合っているか検査する
CloudFormation Linter(cfn-lint)をインストールして、テンプレートをデプロイする前に書き方の間違いに気づけるようにしましょう。
Pythonのpipを使用するため少し導入のハードルが高いですが、CloudFormationテンプレートを開発するならばほぼ必須のツールだと思います。
具体的なインストール方法や使い方はここでは省略します。
Discussion