こんにちは。河内です。
Kubernates の manifest や CI の設定などなど、仕事の中で YAMLを書く機会は結構あるかと思います。 YAML にも若干の構造化機能があるものの限定的であり、例えばCIで複雑なジョブ構成を定義しようとすると、巻物のように長いYAMLファイルができたりします。 長いYAMLファイルはメンテナンス性が悪く、扱っていてなかなか辛いものがあります。
一方 jsonnet は JSON を吐き出せる data templating language です。
ここでは、お手元にある長い YAML の代わりに jsonnet を使うことで、快適な生活を手に入れるための移行パスについて説明します。
JSON は両方のサブセット
移行でのポイントが2点あります。
YAML Ain’t Markup Language (YAML™) revision 1.2.2 によれば、YAML 1.2 では JSON の厳密なスーパーセットとすることに注力した(Its primary focus was making YAML a strict superset of JSON.)と書かれています。 実際に厳密かどうかは把握していませんが、今までで困ったことはないので、ここではJSONはYAMLとみなして話を進めます。 困ったときは JSON から YAML に変換するツールを使うことにしましょう。
移行手順
YAML から JSON に変換するツールを使って、お手元の YAML を JSON に変換します。ポイント1 より JSON は jsonnet とみなせるので、変換後の内容は *.jsonnet ファイルに書き込みます。
変換するツールは何を使っても良いのですが、例えば yq コマンドで変換できます。
$ yq eval -o json my_long.yaml > my_long.jsonnet
JSON はコメントをかけないので、元ファイルにあったコメントは手動で *.jsonnet ファイルに移します。
これ以降、変更を加える際は *.jsonnet ファイルの方を編集します。 変数を使ったり、関数を使ったり、素のYAML には無い便利さを実感できます。
YAML の生成
jsonnet コマンドを実行すると JSON が生成されます。 ポイント2 より JSON は(ほぼ) YAML とみなせるので、生成物を *.yaml とします。
$ jsonnet -o my_generated_long.yaml my_long.jsonnet
これで、 jsonnet を使って快適に編集し、コマンドで YAML を生成できるようになりました。
強すぎる力は身を滅ぼす(かもしれない
jsonnet の代わりに、JavaScript/TypeScript を使ってプログラム的に設定を生成する方法を、似た状況で採用したことがあります。
jsonnet を使う利点は、設定を構造化する上で十分な機能がありながらも、それ以上の機能がないところかと思います。JavaScript/TypeScript のような汎用プログラミング言語では、何でもできてしまうがゆえに、度を超えて複雑な仕組みを作ってしまうリスクがあります。人間、力を持つと使いたくなってしまうもの、かもしれません。
機能性で言えば YAML < jsonnet < 汎用プログラミング言語であり、自身の置かれた状況を理解して、最適な選択をすることが大事かと思います。最適な技術が最高の選択肢、ですね。