ファイルのある場所から別の場所にYAMLブロックをコピーしたことがあれば、 アンカーとエイリアスが解決する問題にすでに直面したことがあります。大規模なKubernetes 設定、マルチ環境のDocker Composeファイル、複雑なCIパイプラインは、 同じブロック—リソース制限、環境変数、ボリュームマウント—を繰り返す傾向があります。 YAMLにはこれに対する組み込みの答えがあり、ほとんどの開発者はそれが存在することを知りません。
アンカー(&)とエイリアス(*)は、値を一度定義して同じファイルの他の場所で参照するYAMLのメカニズムです。
アンカーは変数の宣言、エイリアスはその使用と考えてください。
マージキー(<<)はこれをオブジェクトのマージに拡張します—JavaScriptのスプレッド演算子に似ています。
両方の機能はYAML 1.2仕様のノードアンカーセクションで定義されています。
アンカーとエイリアスの基本構文
構文は最小限です。アンカーを作成するには値に&名前をプレフィックスとして付け、
ドキュメントの任意の場所で*名前を使って参照します:
# Define the anchor once
default_timeout: &timeout 30
# Reference it multiple times
services:
api:
timeout: *timeout # → 30
worker:
timeout: *timeout # → 30
scheduler:
timeout: *timeout # → 30YAMLパーサーがこれを読むと、各エイリアスはアンカーとまったく同じ値に解決されます。 アンカーを変更するとすべてのエイリアスが更新されます。検索・置換は不要です。
<<キーによるオブジェクトのマージ
スカラーの再利用は便利ですが、本当の力はマッピングブロック全体のマージから来ます。
<<マージキーは参照されたアンカーのすべてのキーと値のペアを現在のマッピングに取り込みます:
# Define a base configuration block
base_service: &base
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
networks:
- app-network
# Merge it into specific services
services:
api:
<<: *base # merge all keys from base_service
image: my-api:latest
ports:
- "8080:8080"
worker:
<<: *base # same base config
image: my-worker:latest
command: ["node", "worker.js"]
scheduler:
<<: *base # and again
image: my-scheduler:latest
command: ["node", "cron.js"]マッピングに直接定義されたキーはマージされたアンカーのキーを上書きします。
baseがrestart: unless-stoppedを設定し、サービスも
restart: noを設定している場合、サービスレベルの値が優先されます。
変更前と変更後:実際のDocker Compose
アンカーなしの典型的なマルチサービスDocker Composeファイルはどのように見えるか—繰り返しだらけです:
# BEFORE — repetitive and hard to maintain
version: "3.9"
services:
api:
restart: unless-stopped
env_file: .env
networks: [app-network]
logging:
driver: json-file
options:
max-size: "10m"
depends_on:
- postgres
worker:
restart: unless-stopped
env_file: .env
networks: [app-network]
logging:
driver: json-file
options:
max-size: "10m"
depends_on:
- postgres
mailer:
restart: unless-stopped
env_file: .env
networks: [app-network]
logging:
driver: json-file
options:
max-size: "10m"
depends_on:
- postgresアンカーとマージキーを使うと—各繰り返しブロックが正確に一度だけ定義されます:
# AFTER — DRY and easy to maintain
version: "3.9"
x-common: &common
restart: unless-stopped
env_file: .env
networks: [app-network]
logging:
driver: json-file
options:
max-size: "10m"
depends_on:
- postgres
services:
api:
<<: *common
image: my-api:2.4.1
ports:
- "8080:8080"
worker:
<<: *common
image: my-worker:2.4.1
command: ["node", "worker.js"]
mailer:
<<: *common
image: my-mailer:2.4.1
command: ["node", "mailer.js"]x-プレフィックスを
拡張フィールド
(x-commonなど)に付けるのはDocker Composeの慣習で、ComposeがそのブロックをService定義として解析しようとするのを防ぎます。
Composeエンジンには無視されますが、YAMLアンカーとして完全に使用できます。GitHub Actions:アンカーを使ったMatrix戦略
CI設定はアンカーが効果を発揮する別の場所です。複数のJobにわたって共通のステップ設定を 再利用するGitHub Actionsワークフローの例です:
name: Build and Test
on: [push, pull_request]
# Shared setup steps
x-setup-steps: &setup-steps
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
- run: npm ci
jobs:
lint:
runs-on: ubuntu-latest
steps:
- *setup-steps
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- *setup-steps
- run: npm test -- --coverage
build:
runs-on: ubuntu-latest
steps:
- *setup-steps
- run: npm run build注意:GitHub ActionsのYAMLパーサー はアンカーとエイリアスをサポートしています。ただし一部のCIシステム (特にバージョン2.1以前のCircleCI)はアンカーに似た独自の拡張構文を持っていました。 必ず特定のツールのドキュメントを確認してください。
Kubernetes:リソース制限の再利用
Kubernetesマニフェストでは、リソース制限と環境変数がアンカーの主要な候補です。 私が定期的に使うパターンを紹介します:
# Anchors at the top of the file (or in a shared ConfigMap generator)
x-resources:
small: &resources-small
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "200m"
large: &resources-large
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "1Gi"
cpu: "1000m"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
template:
spec:
containers:
- name: frontend
image: frontend:latest
resources: *resources-small # reuse small profile
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
template:
spec:
containers:
- name: api
image: api:latest
resources: *resources-large # reuse large profile複数マージと上書き優先度
1つのマッピングで複数のアンカーからマージできます。<<の下にリストとして提供します。
重複キーについては、リストの前のエントリが後のエントリより優先されます:
defaults: &defaults
color: blue
size: medium
weight: light
overrides: &overrides
color: red # will override defaults.color
weight: heavy # will override defaults.weight
result:
<<: [*overrides, *defaults] # overrides takes priority
name: widget
# Result: color=red, size=medium, weight=heavy, name=widget知っておくべき制限事項
- 同一ファイル内のみ。 アンカーとエイリアスは単一のYAMLドキュメントストリーム内でのみ機能します。別のファイルのアンカーを参照することはできません。ファイルをまたいだ再利用には、ツール独自のメカニズムが必要です(例:Helmテンプレート、Kustomize、または
yttのようなYAMLプロセッサ)。 - 計算値なし。 エイリアスはアンカーの値の正確なコピーに解決されます。補間やテンプレートロジックはありません—それはHelmやJinja2のようなツールのためのものです。
- マージキーはYAML拡張です。
<<マージキーはYAML 1.1の拡張で定義されており、コア仕様ではありません。ほとんどのパーサーはサポートしていますが、仕様に厳密に準拠したYAML 1.2パーサーはサポートしない場合があります。 - 循環参照はパーサーを壊します。 ノードをアンカーして、そのノード自身の内部から参照しようとしないでください。技術的に無効です。
- エイリアスはコピーであり参照ではありません。 コード内で解決されたエイリアスの値を変更しても、アンカーや他のエイリアスは変わりません。解析後は独立した値です。
まとめ
YAMLのアンカーとエイリアスは、フォーマットの最も活用されていない機能の1つです。 同じ設定ブロックが2回以上現れる50行以上のYAMLファイルでは、アンカーがほぼ確実に使用されるべきです。 メンテナビリティの改善—ファイル全体を検索するのではなく1つのリソース制限プロファイルや 共有環境変数を変更するだけ—は劇的です。 YAML フォーマッターでアンカーを含むファイルを整理し、 YAML バリデータでアンカー参照が正しく解決されることを確認しましょう。