【アップデート】AWS CloudFormationでYAML形式をサポートしました
ウィスキー、シガー、パイプをこよなく愛する大栗です。
全国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
は環境に合わせて書き換えてください。
{ "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へ変換すると以下のようになります。
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
を使用するとコマンドやスクリプトが簡単に記述できるので、テンプレートの作成が捗りますね!