この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
ウィスキー、シガー、パイプをこよなく愛する大栗です。
全国1億3000万人のCloudFormation職人の皆様!先程CloudFormation始まって以来の大きなアップデートが来ました。そうです、YAMLでCloudFormationテンプレートが書けるようになりました。よくJSONは『人間が書くものじゃない』と言われますが、人間が書けるYAMLで記述できるようになりました!
AWS CloudFormation Introduces YAML Template Support and Cross Stack References
AWS CloudFormation Update – YAML, Cross-Stack References, Simplified Substitution | AWS Blog
JSON形式の内容
先日のブログ(CloudFormationで再起動が必要なソフトウェアをインストールする)の内容を元にYAML形式に書き換えてみます。
元の内容は以下の様になっています。なお、KeyPairName
は環境に合わせて書き換えてください。
template.json
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Linux Stack",
"Resources" : {
"Server01": {
"Type": "AWS::EC2::Instance",
"CreationPolicy" : {
"ResourceSignal": {
"Timeout": "PT30M"
}
},
"Properties": {
"ImageId": "ami-0f19db6e",
"InstanceType": "c4.large",
"KeyName": "KeyPairName",
"UserData": { "Fn::Base64": { "Fn::Join": [ "", [
"<script>", "\n",
"cfn-init.exe -v -c install -s ", { "Ref": "AWS::StackId" }, " -r Server01 -c sample --region ", { "Ref": "AWS::Region" }, "\n",
"", "\n",
"</script>"
]]}}
},
"Metadata" : {
"AWS::CloudFormation::Init" : {
"configSets" : {
"sample" : [
"KB3134758",
"vscode",
"finalize"
]
},
"KB3134758" : {
"files" : {
"c:\\cm\\Win8.1AndW2K12R2-KB3134758-x64.msu" : {
"source" : "https://download.microsoft.com/download/2/C/6/2C6E1B4A-EBE5-48A6-B225-2D2058A9CEFB/Win8.1AndW2K12R2-KB3134758-x64.msu"
}
},
"commands" : {
"wait" : {
"command" : "wusa.exe c:\\cm\\Win8.1AndW2K12R2-KB3134758-x64.msu /quiet /forcerestart",
"cwd" : "C:\\cm"
"waitAfterCompletion": "forever"
}
}
},
"vscode" : {
"commands" : {
"a-set-execution-policy": {
"command": "powershell.exe -command Set-ExecutionPolicy RemoteSigned -Force"
},
"b-find-package-provider": {
"command": "powershell.exe -command Find-PackageProvider -ForceBootstrap"
},
"c-find-package": {
"command": "powershell.exe -command Find-Package -ForceBootstrap -Name VisualStudioCode -Provider chocolatey"
},
"d-install-package": {
"command": "powershell.exe -command Install-Package -Name VisualStudioCode -Force"
}
}
},
"finalize" : {
"commands" : {
"a-write-status" : {
"command" : { "Fn::Join": [ "", [
"cfn-signal",
" --exit-code 0",
" --region \"", { "Ref": "AWS::Region" }, "\"",
" --resource Server01",
" --stack \"", { "Ref": "AWS::StackName"}, "\""
]]}
}
}
}
}
}
}
}
}
単純にYAML化する
JSONをYAMLにすると言うことでCloudFormationテンプレートをYAMLで書いてみる【remarshal】を参考にremarshalでYAML化してみます。
$ cat ./01.json | json2yaml > ./02.yaml
YAMLへ変換すると以下のようになります。
02.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Linux Stack
Resources:
Server01:
CreationPolicy:
ResourceSignal:
Timeout: PT30M
Metadata:
AWS::CloudFormation::Init:
KB3134758:
commands:
wait:
command: wusa.exe c:\cm\Win8.1AndW2K12R2-KB3134758-x64.msu /quiet /forcerestart
cwd: C:\cm
waitAfterCompletion: forever
files:
c:\cm\Win8.1AndW2K12R2-KB3134758-x64.msu:
source: https://download.microsoft.com/download/2/C/6/2C6E1B4A-EBE5-48A6-B225-2D2058A9CEFB/Win8.1AndW2K12R2-KB3134758-x64.msu
configSets:
sample:
- KB3134758
- vscode
- finalize
finalize:
commands:
a-write-status:
command:
Fn::Join:
- ""
- - cfn-signal
- ' --exit-code 0'
- ' --region "'
- Ref: AWS::Region
- '"'
- ' --resource Server01'
- ' --stack "'
- Ref: AWS::StackName
- '"'
vscode:
commands:
a-set-execution-policy:
command: powershell.exe -command Set-ExecutionPolicy RemoteSigned -Force
b-find-package-provider:
command: powershell.exe -command Find-PackageProvider -ForceBootstrap
c-find-package:
command: powershell.exe -command Find-Package -ForceBootstrap -Name
VisualStudioCode -Provider chocolatey
d-install-package:
command: powershell.exe -command Install-Package -Name VisualStudioCode
-Force
Properties:
ImageId: ami-0f19db6e
InstanceType: c4.large
KeyName: KeyPairName
UserData:
Fn::Base64:
Fn::Join:
- ""
- - <script>
- |2+
- 'cfn-init.exe -v -c install -s '
- Ref: AWS::StackId
- ' -r Server01 -c sample --region '
- Ref: AWS::Region
- |2+
- ""
- |2+
- </script>
Type: AWS::EC2::Instance
このように普通にCloudFormation Stackを起動できます。
起動したEC2インスタンスもVisual Studio Codeがインストールされます。
YAMLを整形する
remarshal(json2yaml)を使用すると簡単にYAML化できますが、a-write-status
の内容やUserData
が分かりにくくなっています。ここの内容を書き換えます。
YAML形式のサポートと共に文字列置換が簡単になっていますのでFn::Sub
関数で書き換えてみます。YAML形式では"Fn::Sub": String
という表記を!Sub String
という形式でも記述できます。
!Sub String
で書き換える
元は以下の内容となっています。
UserData:
Fn::Base64:
Fn::Join:
- ""
- - <script>
- |2+
- 'cfn-init.exe -v -c install -s '
- Ref: AWS::StackId
- ' -r Server01 -c sample --region '
- Ref: AWS::Region
- |2+
- ""
- |2+
- </script>
!Sub String
を使って書き換えると、以下のようにスッキリします。
UserData:
Fn::Base64: !Sub |
<script>
cfn-init.exe -v -c install -s ${AWS::StackId} -r Server01 -c sample --region ${AWS::Region}
</script>
a-write-status
も同様に書き換えましょう。元の内容は以下になります。
a-write-status:
command:
Fn::Join:
- ""
- - cfn-signal
- ' --exit-code 0'
- ' --region "'
- Ref: AWS::Region
- '"'
- ' --resource Server01'
- ' --stack "'
- Ref: AWS::StackName
- '"'
!Sub String
を使って書き換えると、1行で既述できます。
a-write-status:
command: !Sub |
cfn-signal --exit-code 0 --region "${AWS::Region}" --resource Server01 --stack "${AWS::StackName}"
YAML形式の最終型
remarshal(json2yaml)を使用すると項目の順番がソートされてしまうので、JSON形式と同様の順番に入れ替えると最終的に以下のようになります。
AWSTemplateFormatVersion: 2010-09-09
Description: Linux Stack
Resources:
Server01:
Type: AWS::EC2::Instance
CreationPolicy:
ResourceSignal:
Timeout: PT30M
Properties:
ImageId: ami-0f19db6e
InstanceType: c4.large
KeyName: KeyPairName
UserData:
Fn::Base64: !Sub |
<script>
cfn-init.exe -v -c install -s ${AWS::StackId} -r Server01 -c sample --region ${AWS::Region}
</script>
Metadata:
AWS::CloudFormation::Init:
configSets:
sample:
- KB3134758
- vscode
- finalize
KB3134758:
files:
c:\cm\Win8.1AndW2K12R2-KB3134758-x64.msu:
source: https://download.microsoft.com/download/2/C/6/2C6E1B4A-EBE5-48A6-B225-2D2058A9CEFB/Win8.1AndW2K12R2-KB3134758-x64.msu
commands:
wait:
command: wusa.exe c:\cm\Win8.1AndW2K12R2-KB3134758-x64.msu /quiet /forcerestart
cwd: C:\cm
waitAfterCompletion: forever
vscode:
commands:
a-set-execution-policy:
command: powershell.exe -command Set-ExecutionPolicy RemoteSigned -Force
b-find-package-provider:
command: powershell.exe -command Find-PackageProvider -ForceBootstrap
c-find-package:
command: powershell.exe -command Find-Package -ForceBootstrap -Name VisualStudioCode -Provider chocolatey
d-install-package:
command: powershell.exe -command Install-Package -Name VisualStudioCode -Force
finalize:
commands:
a-write-status:
command: !Sub |
cfn-signal --exit-code 0 --region "${AWS::Region}" --resource Server01 --stack "${AWS::StackName}"
さいごに
全てのCloudFormation職人が待ち望んでいたYAML対応がされました。またCloudFormationで一番面倒なのがUserData
やMetadata
でのコマンドやスクリプトの記述でした。JSONの場合は元のスクリプトをエスケープして記述する必要があり、変数の埋め込みも大変でした。Fn::Sub
や!Sub String
を使用するとコマンドやスクリプトが簡単に記述できるので、テンプレートの作成が捗りますね!