Docker ComposeでDB接続情報を各サービスに毎回コピペしていて、1箇所修正するたびに直し漏れが発生していました。アンカーとマージキーの存在を知ってからは、共通設定を1箇所に集約できるようになり、書き漏れの事故が明確に減りました。
アンカー(&)と参照(*)の基本
図1: &で定義した値を、*とマージキー<<で再利用する
アンカー(&名前)はノード(値)に名前を付ける機能で、参照(*名前)はそのアンカーが指す値をそのままコピーして展開する機能です。同じ値を何度も書く代わりに、1箇所で定義して使い回せます。
default_timeout: &timeout 30
api_client:
connect_timeout: *timeout
read_timeout: *timeout
&timeout で値 30 に timeout という名前を付け、*timeout でその値を参照しています。結果として connect_timeout と read_timeout は両方とも 30 になります。値そのものだけでなく、マッピングやシーケンス全体にアンカーを付けることもできます。
マージキー(<<)による結合
マッピング全体を再利用しつつ、一部だけ上書きしたい場合に使うのがマージキー(<<)です。アンカーで定義したマッピングを丸ごと展開し、同じキーがあれば自分の定義で上書きします。
defaults: &defaults
adapter: postgres
host: localhost
pool: 5
development:
<<: *defaults
database: dev_db
production:
<<: *defaults
database: prod_db
host: db.prod.internal # defaultsのhostを上書き
pool: 20 # defaultsのpoolを上書き
production は &defaults の3項目をすべて引き継ぎつつ、host と pool だけを独自の値で上書きしています。同じ設定を何度も書き写す必要がなくなり、修正漏れも防げます。
⚠️ マージキーはYAML 1.1由来の慣習的な拡張構文
<< はYAML本体のコア仕様(YAML 1.2)には含まれておらず、多くの実装が慣習として対応している拡張構文という位置づけです。使用する言語のYAMLパーサーが対応しているか、事前に確認してください(Python の PyYAML、Ruby の Psych など主要な実装は概ね対応しています)。
複数ドキュメント(---, ...)
1つのファイルに複数の独立したYAMLドキュメントをまとめたい場合、---(3つのハイフン)で区切ります。ドキュメントの終端を明示したい場合は ...(3つのピリオド)を使いますが、省略されることも多いです。
apiVersion: v1
kind: Service
metadata:
name: web-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
この記法はKubernetesのマニフェストファイルで特に頻繁に使われます。1つの kubectl apply -f コマンドで、複数のリソース定義をまとめてクラスタに適用できるためです。プログラムからパースする場合、多くのYAMLライブラリには「複数ドキュメントを順番に読み込む」専用の関数が用意されています(PythonのPyYAMLなら yaml.safe_load_all())。
フロースタイル(インライン記法)
ここまで見てきたインデントベースの書き方をブロックスタイルと呼びます。一方でYAMLには、JSONのように {} と [] を使って1行で書くフロースタイルも用意されています。
# ブロックスタイル
person:
name: Alice
age: 30
tags:
- admin
- staff
# 同じ内容をフロースタイルで書いた場合
person: { name: Alice, age: 30, tags: [admin, staff] }
フロースタイルはJSONとの親和性が高く、実際ほとんどのJSONファイルはそのまま有効なYAMLとして読み込めます(JSONはYAMLのフロースタイルのサブセットに近い関係にあります)。短い設定を1行にまとめたいときや、他形式からの変換結果を扱うときに使われますが、可読性の観点から長い構造はブロックスタイルで書くのが一般的です。
特殊文字のエスケープと複数行文字列
コロンやハイフンなど、YAMLの記法として意味を持つ文字を文字列の一部として使いたい場合は、クォートで囲みます。シングルクォートとダブルクォートには挙動の違いがあります。
| クォート | 特徴 |
|---|---|
| なし(プレーン) | 最も一般的。ただし特殊文字を含む場合や数値・真偽値と誤解されそうな文字列には使えない |
シングルクォート '...' | エスケープシーケンスを解釈しない。'自体を含めるには''と2つ重ねる |
ダブルクォート "..." | \nや\tなどのエスケープシーケンスを解釈できる |
time_format: "12:30:00" # コロンを含むためクォート必須
country_code: "NO" # 真偽値と誤解されるのを防ぐ
path: 'C:\Users\name' # シングルクォートならバックスラッシュはそのまま
message: "Line1\nLine2" # ダブルクォートでエスケープシーケンスを解釈
複数行の長いテキスト(説明文やスクリプト本体など)を書きたい場合は、ブロックスカラーと呼ばれる |(リテラル)または >(フォールド)を使います。
# | : 改行をそのまま保持する
script: |
echo "start"
npm install
npm run build
# > : 改行をスペースに変換して1行の文章として畳み込む
description: >
これは複数行にわたって書かれた
長い説明文ですが、実際には
スペース区切りの1行として扱われます。
💡 使い分けの目安
コマンドの羅列やコードなど、改行そのものに意味がある場合は | を、長い説明文のように改行を気にせず読めればよい場合は > を使うと覚えると迷いません。
まとめ
| 記法 | 役割 |
|---|---|
&名前 / *名前 | 値に名前を付けて再利用する(アンカー/参照) |
<<: *名前 | マッピングを丸ごと展開し、一部だけ上書きする(マージキー) |
--- | 1ファイルに複数のドキュメントをまとめる区切り |
{ } / [ ] | JSON風に1行で書くフロースタイル |
'...' / "..." | 特殊文字を含む文字列を明示的に区切る |
| / > | 複数行文字列(改行を保持/畳み込む) |
✅ 次の章では…
PART 05(最終回)では、ここまでの記法を前提に、チームで記述ルールを統一する考え方と、yamllintルールのカスタマイズ、CI(GitHub Actions)への組み込み方を解説し、シリーズ全体をまとめます。