この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、虎塚です。
CloudFormationのテンプレートをJSONで書く時、ファイルが巨大になってくると読み書きが大変ですよね。バリデーションや入力補完などのエディタサポートがもっと欲しいという話もありますが、今日はフォーマットの話にフォカースしてみます。
こんな要望はありませんでしょうか?
- コメントを書きたい
- ブロックコメントを書きたい
- あわよくば日本語でコメントを書きたい
- Description要素などの長文文字列が読みづらいので何とかしたい
- 配列要素の末尾にカンマを許して欲しい
- 要素をコピーアンドペーストするたびに、カンマを付けたり消したりしたくない
CloudFormationのテンプレートに限らず、JSONにはこれらの問題が付き物なので、拡張フォーマットがいくつか存在します。
今回はそれらの中の1つであるJSON5でCloudFormationのテンプレートを書いてみます。
JSON5でテンプレートを書く
元となるテンプレート
題材として、AWSが提供しているサンプルテンプレートを見てみましょう。
上記のテンプレート群から1つ選択して、JSON5に書き換えてみます。ここでは、EC2WithEBSPIOPs.templateを使いました。
Amazon EC2 インスタンスと、プロビジョンド IOP を備えた EBS ボリュームを作成します。
AWS CloudFormation サンプルテンプレート – アジアパシフィック(東京)リージョン
というテンプレートです(実際のJSONファイル)。
JSON5で書いてみる
上のテンプレートに、JSON5で使える要素を加えて改変すると、次のようになります。
{
"AWSTemplateFormatVersion" : "2010-09-09",
/*
2014年8月 XYZ案件向けベーステンプレート
-- 複数行コメントのテスト
*/
// 複数行にわたる文字列をバックスペースで区切って改行するテスト
"Description" : "AWS CloudFormation Sample Template EC2WithEBSPIOPs: \
Create an Amazon EC2 instance running the Amazon Linux AMI with \
a new EBS volume attached that has provisioned IOPs. \
The instance and the volume are pinned to the same availability zone. \
We recommend that you do untargeted launches rather than pinning instances this way.\
The AMI is chosen based on the region in which the stack is run. \
**WARNING** This template creates an Amazon EC2 instance and an EBS Volume. \
You will be billed for the AWS resources used if you create a stack from this template.",
"Parameters" : {
"KeyName": {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"Type": "String",
"MinLength": "1",
"MaxLength": "255",
"AllowedPattern" : "[\\x20-\\x7E]*",
"ConstraintDescription" : "can contain only ASCII characters."
},
"SSHFrom" : {
"Description" : "Lockdown SSH access (default can be accessed from anywhere)",
"Type" : "String",
"MinLength": "9",
"MaxLength": "18",
"Default" : "0.0.0.0/0",
"AllowedPattern" : "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription" : "must be a valid CIDR range of the form x.x.x.x/x."
}
},
// 新しいAMIが出たら差し替えること -- 1行コメントのテスト
"Mappings" : {
"RegionMap" : {
"us-east-1" : { "AMI" : "ami-aecd60c7" },
"us-west-2" : { "AMI" : "ami-48da5578" },
"us-west-1" : { "AMI" : "ami-734c6936" },
"eu-west-1" : { "AMI" : "ami-6d555119" },
"ap-southeast-1" : { "AMI" : "ami-3c0b4a6e" },
"ap-southeast-2" : { "AMI" : "ami-bd990e87" },
"ap-northeast-1" : { "AMI" : "ami-2819aa29" },
// 配列の末尾要素にカンマを足すテスト(いわゆるケツカンマ)
"sa-east-1" : { "AMI" : "ami-fe36e8e3" },
}
},
"Resources" : {
"EC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ],
"InstanceType" : "m1.large",
"KeyName" : { "Ref" : "KeyName" },
"ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
"EbsOptimized" : "true"
}
},
"InstanceSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Enable SSH access via port 22",
"SecurityGroupIngress" : [ {
"IpProtocol" : "tcp",
"FromPort" : "22",
"ToPort" : "22",
"CidrIp" : { "Ref" : "SSHFrom" }
} ]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "EC2Instance" },
"VolumeId" : { "Ref" : "NewVolume" },
"Device" : "/dev/sdh"
}
},
"NewVolume" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "100",
"VolumeType" : "io1",
"Iops" : "100",
"AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]}
}
}
},
"Outputs" : {
"InstanceId" : {
"Description" : "InstanceId of the newly created EC2 instance",
"Value" : { "Ref" : "EC2Instance" }
}
}
}
- コメントを書いた
- ブロックコメント(複数行コメント)を書いた
- 日本語でコメントを書いた
- 長文文字列を改行した
- 配列要素の末尾にカンマを付けた
このような変更を加えました。このファイルをEC2WithEBSPIOPs.json5という名前で保存します。
JSON5のインストール
上のファイルをCloudFormationのテンプレートとして利用するには、JSON5からJSONへと変換する必要があります。
JSON5 to JSONのコンバートコマンドを使うために、JSON5をインストールしましょう。
Mac OS X 10.9.4 (13E28) で動作確認しました。
node.jsのインストール
Node.jsをインストールします。HomeBrewを使うと簡単です。
brew caskを使う場合、次のコマンドを実行します。
brew cask install node
この時、Node.jsの実行環境と一緒にnpm(パッケージ管理ツール)もインストールされます。
JSON5のインストール
npmでJSON5をインストールします。グローバル領域にインストールする場合、次のコマンドを実行します。
% sudo npm install -g json5
Password:
/usr/local/bin/json5 -> /usr/local/lib/node_modules/json5/lib/cli.js
json5@0.2.0 /usr/local/lib/node_modules/json5
% which json5
/usr/local/bin/json5
JSON5をJSONへ変換する
次のコマンドを実行するだけで、JSON5からJSONへ変換できます。
json5 -c EC2WithEBSPIOPs.json5
EC2WithEBSPIOPs.jsonというファイルが、カレントディレクトリに生成されます。
確認
EC2WithEBSPIOPs.jsonを指定して、CloudFormationでスタックを作ってみましょう。
JSONファイルなので当たり前ではありますが、改変前のテンプレートと同様に、まったく問題なくスタックが作成されました。
ちょっとしたコツ
Macでのバックスラッシュの入力方法
複数行の文字列を改行するために、バックスラッシュを入力するとき、Macでエンマーク(¥)を使うとエラーになってしまいます。Macでバックスラッシュを入力するには、「optionキー + ¥」を入力します。
文字列の中にマルチバイト文字を入れてはいけない
JSON5ではコメントでマルチバイト文字が使えるので、つい文字列の中に日本語を書いてしまうことがありますが、CloudFormationのテンプレートとしては使えませんので気をつけましょう。
文字列中にマルチバイト文字がある状態でコンバートを実行しても成功するので、気づきにくいところです。注意しましょう。
数字や真偽値のダブルクォーテーションは外さない
数字や真偽値にダブルクォーテーションを付けなくてよいのも、JSON5の魅力のひとつです。しかし、それらも文字列として扱わなければ、CloudFormationのテンプレートとしてはエラーになります。
おわりに
誰かが作った巨大なテンプレートを読み解く時はもちろん、テンプレートを他の人へ引き継ぐ時などに、テンプレートへ注釈を書きたくなったら、JSON5を使ってみてもいいかもしれませんね。
それでは、また。