AWSがGitHubで公開しているCloudFormationの変換ツールを使ってみた
はじめに
こんにちは、中山です。
先日AWSがGitHub上に開設しているアカウントを見ていたのですが、便利そうなツールを発見したので本エントリでご紹介したいと思います。aws-cfn-template-flipというCloudFormation(以下CFn)をJSON/YAML間で変換するツールです。READMEに分かりやすい説明が記載されているので以下に引用します。
AWS CloudFormation Template Flip is a tool that converts AWS CloudFormation templates between JSON and YAML formats, making use of the YAML format’s short function syntax where possible.The term "Flip" is inspired by the well-known Unix command-line tool flip which converts text files between Unix, Mac, and MS-DOS formats.
以前弊社のエントリでRubyのワンライナーを利用したJSON/YAML間の変換方法をご紹介しました。
これはこれでとても便利なのですが、単純に変換しているだけなのでCFnの短縮表記まで変換することはできません。また、AWSが公開しているツールという点も何となく安心できるポイントだと思います。基本的にコマンドラインから利用することが多いと思いますが、モジュールとしても利用可能なので、PythonからCFnテンプレートを生成しているようなケースでも使えます。
なお、本エントリを執筆する上で検証に利用した主要な各種ツールのバージョンは以下の通りです。バージョンによって結果が変更される可能性があるので、その点ご了承ください。
- aws-cfn-template-flip: 0.2.1
使ってみる
インストールは簡単です。 pip
コマンドでインストールするだけです。
$ pip install cfn_flip
インストールが完了すると cfn-flip
というコマンドが利用できます。 -h
オプションでヘルプが表示されます。
$ cfn-flip -h usage: cfn-flip [-h] [-c] [input] [output] AWS CloudFormation Template Flip is a tool that converts AWS CloudFormation templates between JSON and YAML formats, making use of the YAML format's short function syntax where possible. positional arguments: input File to read from. If you do not supply a file, input will be read from stdin. output File to write to. If you do not supply a file, output will be written to stdout. optional arguments: -h, --help show this help message and exit -c, --clean Performs some opinionated cleanup on your template. For now, this just converts uses of Fn::Join to Fn::Sub.
リポジトリにテスト用のCFnテンプレートが用意されているので、それを利用して試してみましょう。まずはJSONからYAMLに変換してみます。元となるJSONは以下の通りです。
examples/clean.json
{ "Description": "Test", "Foo": { "Fn::Sub": "The ${cake} is a lie" }, "Bar": { "Fn::Base64": { "Ref": "Binary" } } }
対象ファイルの読み込み方法や出力方法は複数用意されています。
# 標準入力から対象ファイルを読み込み $ cat examples/clean.json | cfn-flip Description: Test Foo: !Sub 'The ${cake} is a lie' Bar: !Base64 Ref: Binary # 引数で対象ファイルを読み込み $ cfn-flip examples/clean.json Description: Test Foo: !Sub 'The ${cake} is a lie' Bar: !Base64 Ref: Binary # 別ファイルに出力 $ cfn-flip examples/clean.json clean.yml && cat clean.yml Description: Test Foo: !Sub 'The ${cake} is a lie' Bar: !Base64 Ref: Binary
-c
オプションを指定すると現時点(2017/03/10)ではFn::Join関数をFn::Sub関数に変換してくれます。一部 Fn::Sub
が対応していない場合などがあるのですが、 Fn::Join
より可読性が高いので基本的にこのオプションを使った方がよいかと思います。 Fn::Join
を含んだCFnテンプレートも用意してくれているのでそれを使って結果を確認してみます。元となるファイルは以下です。
examples/test.json
{ "Description": "Test", "Foo": { "Fn::Join": [ " ", [ "The", { "Ref": "cake" }, "is", "a", "lie" ] ] }, "Bar": { "Fn::Base64": { "Ref": "Binary" } } }
結果は以下のようになります。最高ですね。
$ cfn-flip -c examples/test.json Description: Test Foo: !Sub 'The ${cake} is a lie' Bar: !Base64 Ref: Binary
Pythonモジュールとして利用する場合は以下のように使えます。コマンドラインと基本的に同じ感覚で利用可能です。
# メソッドのインポート In [1]: from cfn_flip import flip, to_yaml, to_json # JSONファイルを読み込むと自動でYAMLに変換してくれる In [2]: with open('examples/clean.json') as f: ...: clean_yaml = flip(f.read()) ...: In [3]: clean_yaml Out[3]: "Description: Test\nFoo: !Sub 'The ${cake} is a lie'\nBar: !Base64\n Ref: Binary\n" # YAMLからJSONへの変換 In [4]: to_json(clean_yaml) Out[4]: '{\n "Description": "Test", \n "Foo": {\n "Fn::Sub": "The ${cake} is a lie"\n }, \n "Bar": {\n "Fn::Base64": {\n "Ref": "Binary"\n }\n }\n}' # JSONからYAMLへの変換 In [5]: to_yaml(to_json(clean_yaml)) Out[5]: "Description: Test\nFoo: !Sub 'The ${cake} is a lie'\nBar: !Base64\n Ref: Binary\n" # clean_up=Trueにすると-cオプションと同等の処理をしてくれる In [6]: with open('examples/test.json') as f: ...: print(to_yaml(f.read(), clean_up=True)) ...: Description: Test Foo: !Sub 'The ${cake} is a lie' Bar: !Base64 Ref: Binary
まとめ
いかがだったでしょうか。
AWSが公開しているCFn変換ツールをご紹介しました。CFnのYAML対応は比較的最近です。既存プロジェクトではJSON業に励んでいた方も多いかと思いますが、このツールを利用することで簡単にYAMLへ変換できそうですね。
本エントリがみなさんの参考になれば幸いに思います。