FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

YAML から jsonnet に乗り換えて快適な生活を送る方法

こんにちは。河内です。

Kubernates の manifest や CI の設定などなど、仕事の中で YAMLを書く機会は結構あるかと思います。 YAML にも若干の構造化機能があるものの限定的であり、例えばCIで複雑なジョブ構成を定義しようとすると、巻物のように長いYAMLファイルができたりします。 長いYAMLファイルはメンテナンス性が悪く、扱っていてなかなか辛いものがあります。

一方 jsonnet は JSON を吐き出せる data templating language です。

jsonnet.org

ここでは、お手元にある長い YAML の代わりに jsonnet を使うことで、快適な生活を手に入れるための移行パスについて説明します。

JSON は両方のサブセット

移行でのポイントが2点あります。

  • ポイント1: JSON は jsonnet とみなせる
  • ポイント2: JSON は(ほぼ) YAML とみなせる

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.)と書かれています。 実際に厳密かどうかは把握していませんが、今までで困ったことはないので、ここではJSONYAMLとみなして話を進めます。 困ったときは JSON から YAML に変換するツールを使うことにしましょう。

移行手順

YAML から JSON に変換するツールを使って、お手元の YAMLJSON に変換します。ポイント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 < 汎用プログラミング言語であり、自身の置かれた状況を理解して、最適な選択をすることが大事かと思います。最適な技術が最高の選択肢、ですね。