この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。サービスグループの武田です。
現在運用しているAWS CloudFormationスタックがあるのですが、そのテンプレートはJSONで書かれています。それをYAMLに書き換えた上でシームレスにスタック更新が可能かが調べても分からなかったため試してみました。
環境
次の環境で検証しました。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G65
$ aws --version
aws-cli/1.15.33 Python/3.6.5 Darwin/17.7.0 botocore/1.10.33
$ jq --version
jq-1.5
$ pip -V
pip 18.0 from /usr/local/lib/python3.6/site-packages/pip (python 3.6)
やってみた
まずはベースとなるJSONファイルを用意します。作成するリソースはなんでもよかったのですが、あたり障りのないセキュリティグループにしました。ファイル名はmig-test.template.json
です。
mig-test.template.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "CFn migration test",
"SecurityGroupIngress": [
{
"IpProtocol": "TCP",
"FromPort": 80,
"ToPort": 80,
"CidrIp": "0.0.0.0/0"
}
]
}
}
}
}
このテンプレートを使ってスタックを作成します。
$ aws cloudformation create-stack \
--stack-name mig-test \
--template-body file://mig-test.template.json
$ aws ec2 describe-security-groups \
--group-names $(aws cloudformation describe-stack-resource \
--stack-name mig-test \
--logical-resource-id SecurityGroup \
| jq -r '.StackResourceDetail.PhysicalResourceId')
{
"SecurityGroups": [
{
"Description": "CFn migration test",
"GroupName": "mig-test-SecurityGroup-1WPEQP3XYW2PP",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"ToPort": 80,
"UserIdGroupPairs": []
}
],
"OwnerId": "123456789012",
"GroupId": "sg-0cb2dbebe96971562",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"Tags": [
{
"Key": "aws:cloudformation:stack-name",
"Value": "mig-test"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/mig-test/7beeff40-affc-11e8-8b76-50a68669982a"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "SecurityGroup"
}
],
"VpcId": "vpc-1c3e1278"
}
]
}
ちゃんと作成されていますね。続いて先ほど作成したJSONファイルをcfn_flip
でYAMLファイルに変換します。cfn_flip
については中山がエントリを書いていますので参考にしてください。
ファイル名はmig-test.template.yml
としました。
$ pip install cfn_flip
$ cfn-flip mig-test.template.json mig-test.template.yml
YAMLファイルが作成されたら、セキュリティグループにタグを追加してみます。
mig-test.template.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: CFn migration test
SecurityGroupIngress:
- IpProtocol: TCP
FromPort: 80
ToPort: 80
CidrIp: '0.0.0.0/0'
Tags:
- Key: Name
Value: MigTest
それではこのファイルを使ってスタックを更新してみます。
$ aws cloudformation deploy \
--stack-name mig-test \
--template-file mig-test.template.yml
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - mig-test
$ aws ec2 describe-security-groups \
--group-names $(aws cloudformation describe-stack-resource \
--stack-name mig-test \
--logical-resource-id SecurityGroup \
| jq -r '.StackResourceDetail.PhysicalResourceId')
{
"SecurityGroups": [
{
"Description": "CFn migration test",
"GroupName": "mig-test-SecurityGroup-1WPEQP3XYW2PP",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"ToPort": 80,
"UserIdGroupPairs": []
}
],
"OwnerId": "123456789012",
"GroupId": "sg-0cb2dbebe96971562",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"Tags": [
{
"Key": "aws:cloudformation:stack-name",
"Value": "mig-test"
},
{
"Key": "Name",
"Value": "MigTest"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/mig-test/7beeff40-affc-11e8-8b76-50a68669982a"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "SecurityGroup"
}
],
"VpcId": "vpc-1c3e1278"
}
]
}
追加したタグが付与されていることが確認できました。
まとめ
CloudFormationがYAMLをサポートしてもうすぐ2年ですね。すでに運用中のスタックであってもJSONからYAMLへの移行はシームレスにできることがわかりました。JSONで管理しているテンプレートは積極的に移行を計画していきたいですね。