Docker、Kubernetes、GitHub Actions、またはほぼすべてのモダンなDevOpsツールを使っているなら、気づいているかどうかに関わらず、すでにYAMLを使っています。YAML(「YAML Ain't Markup Language」の略 — はい、再帰的な頭字語です)は、最も人間が読みやすいデータフォーマットとして設計されました。
一緒に、一つずつコンセプトを学んでいきましょう。
YAMLが存在する理由
JSONはマシンには最適ですが、200行の設定ファイルをJSONで書こうとしたことはありますか?コメントなし、どこでもダブルクォート必須、5段階にネストされた波括弧…すぐに辛くなります。YAMLはこの問題を解決するために作られました。ブラケットの代わりにインデントを使うことで、設定ファイルがきれいで見やすくなります。
同じデータをJSONとYAMLで見てみましょう。違いがわかりますか?
JSON:
YAML:
知っておくべき基本
キーと値のペアはYAMLの基本中の基本です。コロンとスペースを使うだけ:name: John Doe。それだけです — ほとんどの文字列にクォートは不要です。
インデントがすべてです。 YAMLは構造を示すためにスペース(タブは絶対にダメ!)を使います。標準は1レベルにつき2スペースです。これを間違えるとファイルが壊れます。本当に — YAML仕様はこの点で厳格です。
ネストされたデータの例を見てみましょう:
リストはダッシュとスペースを使います。YAMLでの買い物リストはこんな感じです:
文字列:思ったより厄介
YAMLではほとんどの文字列にクォートは不要です。ただし、コロンやハッシュを含む場合や、誤って解釈される可能性がある場合はクォートを使うべきです。例えば、country: NOはYAML 1.1ではcountry: falseと解釈されます。NOがブーリアンとして扱われるためです。これは有名な「ノルウェー問題」で、実際にプロダクションでバグを引き起こしています。
迷ったらクォートで囲みましょう:country: "NO"
複数行文字列は素晴らしい
ここがYAMLの真価を発揮するところです。パイプ|は改行を保持し(スクリプトに最適)、>は改行をスペースに畳みます(長い説明に最適):
アンカーとエイリアス:DRYな設定ファイル
YAMLの最もクールな機能の一つです。&で一度定義し、後で*で参照します:
productionブロックはdefaultsからretries: 3を継承しつつ、timeoutをオーバーライドします。これはGitHub ActionsワークフローやDocker Composeファイルで非常に便利です。そうでなければ同じ設定ブロックを何度も繰り返すことになります。
YAMLでよくある4つのミス
- スペースの代わりにタブ — エディタがデフォルトでタブを挿入するかもしれません。YAMLファイルにはスペースを使うよう設定してください。本当に、今すぐやりましょう。
- ブーリアンの罠 —
yes、no、on、off、true、falseはYAML 1.1ではすべてブーリアンです。文字列として使いたい場合はクォートを付けましょう。 - 値の中のコロン —
message: Error: file not foundはYAMLが2つ目のキーと値のセパレータと認識するため壊れます。クォートを使いましょう:message: "Error: file not found" - 末尾の空白 — 行末の見えないスペースが奇妙なパース動作を引き起こすことがあります。末尾の空白をハイライトするエディタを使いましょう。
毎日YAMLを使う場所
YAMLはDocker Compose、Kubernetesマニフェスト、GitHub Actions、GitLab CI、Ansibleプレイブックなど数十の設定言語です。DevOpsやクラウドに関わることをしているなら、YAMLの習熟は必須です。
おかしな動きをするYAMLファイルがありますか?YAML Validatorに貼り付けて、問題を即座に見つけましょう。
実践的なYAML:Docker Composeの例
実際のDocker Composeファイルを見てみましょう — Webアプリケーションのために実際に書くような種類のものです:
いくつか注目してください:環境変数はリスト形式(- KEY=value)でもマッピング形式(KEY: value)でも書けます。どちらもDocker Composeで動作しますが、一貫性のために一つのスタイルを選んで統一しましょう。
実践的なYAML:GitHub Actions CIパイプライン
プッシュごとにテストを実行するGitHub Actionsワークフローです:
きれいで、読みやすく、自明です。同じワークフローをJSONで書くことを想像してみてください — 倍の長さになり、視覚的にずっと読みにくくなるでしょう。
YAML vs JSON vs TOML:クイック比較
YAMLは設定ファイルのためのJSON代替として唯一の選択肢ではありません。TOMLも人気の選択肢です(RustのCargo.tomlやPythonのpyproject.tomlで使われています)。比較してみましょう:
| 機能 | YAML | JSON | TOML |
| コメント | あり (#) | なし | あり (#) |
| 可読性 | 優秀 | 良好 | 非常に良好 |
| ネスト構造 | インデント | 波括弧 | セクション/ドット |
| 複数行文字列 | あり (` | , >`) | なし | あり (""") |
| 型推論 | あり(危険な場合あり) | 明示的 | あり(より安全) |
| 末尾カンマ | N/A | 不可 | 可 |
| エコシステム | DevOps, K8s, CI/CD | Web APIs, Node.js | Rust, Python |
上級YAML:1ファイルに複数ドキュメント
YAMLは---で区切ることで、1つのファイルに複数のドキュメントをサポートしています。これはKubernetesで複数のリソースを一度にデプロイする際によく使われます:
---セパレータはYAMLパーサに「これは新しいドキュメントです」と伝えます。このようなファイルにkubectl apply -fを実行すると、Kubernetesが両方のリソースを作成します。
YAMLのセキュリティ:Billion Laughs攻撃
ほとんどの初心者が知らないことがあります:注意しないとYAMLはセキュリティリスクになり得ます。「Billion Laughs」攻撃はアンカーとエイリアスを使って指数関数的なデータ展開を作り出します:
この小さなファイルはメモリ上でギガバイトに展開され、アプリケーションをクラッシュさせる可能性があります。教訓は?信頼できないYAML入力は絶対にパースしないでください。 Pythonではyaml.load()の代わりにyaml.safe_load()のような安全な読み込み関数を使い、YAMLパーサにメモリ制限を設定しましょう。
YAMLとJSON間の変換
YAMLはJSONのスーパーセットなので(はい、有効なJSONは有効なYAMLでもあります!)、両者間の変換は簡単です。これは設定を書くときにYAMLの可読性を活用したいけど、JSONを必要とするAPIやツールがある場合に便利です。
私たちのYAML to JSON Converterなら即座に変換できます — YAMLを貼り付けるだけできれいなJSON出力が得られます。逆方向は?お持ちのJSONはすでに有効なYAMLです。
自分で試してみよう
壊れたKubernetesマニフェストのデバッグでも、新しいCIパイプラインのセットアップでも、これらのツールが時間を節約してくれます:
- YAML Formatter — インデントを修正し、YAMLファイルをきれいで一貫性のあるものにします。
- YAML Validator — デプロイメントを壊す前に構文エラーを検出します。
- YAML to JSON Converter — JSON専用ツールと連携する必要があるときにフォーマット間で変換します。
YAMLには癖がありますが、インデントベースの構文に慣れてしまえば、JSONの代替と比べて設定ファイルがどれほどきれいに見えるかを実感するでしょう。