データ形式 · 2026年8月28日

YAMLのアンカーとエイリアスを説明(コピペ例付き)

YAMLのアンカー(&)とエイリアス(*)は、コピー&ペーストせずに設定を再利用できます。それらの仕組み、使用場面、本番環境で人を騙すエッジケース。

設定ファイルの3つの異なる場所に同じ10行のYAMLをコピー&ペーストしたことがあるなら、YAMLアンカーが解決しようとしている痛みを感じたことがあるだろう。アンカーは値を1回だけ定義し、同じドキュメント内のどこからでも参照できるようにする。値を1箇所で変更すれば、すべての参照が更新される。

この投稿は、アンカーとエイリアスがどのように機能し、いつ使い、人々をひっかけるエッジケースについて説明する。

基本構文

YAMLアンカーはノードに与える名前だ:

defaults: &defaults
  retries: 3
  timeout: 30
  log_level: info

&defaultsがアンカーだ。これはdefaultsの値(マップ)に付与される。アンカーは任意のノードに置ける — 文字列、数値、リスト、マップ、シーケンス。

エイリアスはアンカーへの参照だ:

production:
  <<: *defaults
  region: us-east-1
  replicas: 5

staging:
  <<: *defaults
  region: us-west-2
  replicas: 2

<<: *defaultsは「マージキー」だ。「defaultsというアンカーからすべてを取り込み、このマップにマージする」という意味だ。結果はdefaultsの内容をインラインで書いたのと同じだ:

production:
  retries: 3
  timeout: 30
  log_level: info
  region: us-east-1
  replicas: 5

しかしdefaultsのretriesを変更すると、アンカーを使うすべての場所が更新される。それがポイントだ。

単一値へのアンカー

アンカーはマップにマージする必要はない。単一値にアンカーを付けて参照できる:

api_version: &api "v2.1.0"
services:
  auth:
    version: *api
  billing:
    version: *api
  reports:
    version: *api

これでAPIのバージョンを変更するのは1行の変更だ。参照はすべて追従する。

リストにアンカーを付けることもできる:

allowed_origins: &origins
  - https://app.example.com
  - https://admin.example.com
  - https://staging.example.com

cors:
  web: *origins
  api: *origins

リストはそのまま再利用される。

アンカーが役立つ場合

アンカーは複数のインスタンスに共有デフォルトがある場合に輝く。Kubernetesマニフェスト、docker-composeファイル、CIマトリクスはこのパターンにあふれている。

2026年の注記:HelmとKustomizeがKubernetesテンプレートの主流であり、YAMLのアンカーシステム外で動作する — YAMLを生成し、パースしない。HelmまたはKustomizeを使っているなら、アンカーは不要だ(values.yamlとパッチオーバーレイがある)。アンカーはまだkubectl apply -fワークフロー、GitHub Actionsマトリクス、docker-composeファイル、テンプレートエンジンを通らない手動設定に適している。

Kubernetesの例 — 同じリソース制限を持つ3つのサービス:

base_resources: &base_resources
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

apiDeployment:
  spec:
    template:
      spec:
        containers:
          - name: api
            image: myapp/api:1.2.3
            resources: *base_resources

workerDeployment:
  spec:
    template:
      spec:
        containers:
          - name: worker
            image: myapp/worker:1.2.3
            resources: *base_resources

docker-composeの例 — 開発と本番で同じ環境:

common_env: &common_env
  DATABASE_URL: postgres://db.internal/app
  REDIS_URL: redis://cache.internal:6379
  LOG_LEVEL: info

services:
  api:
    environment:
      <<: *common_env
      ENVIRONMENT: dev
  worker:
    environment:
      <<: *common_env
      ENVIRONMENT: dev

どちらのケースでも、共通環境を変更するのは1行の編集だ。

Gotcha

アンカーは強力だが、いくつかの鋭い刃がある。

アンカーはドキュメント内にローカルだ。 ドキュメント区切り(---)を持つ複数ドキュメントYAMLファイルは、アンカーに独自のスコープを持つ。ドキュメント1で定義されたアンカーはドキュメント2から参照できない。複数リソースのkubectl get -o yamlなど、複数ドキュメントYAMLを生成するツールを使っている場合、アンカーで値を共有できない。

アンカーとマージはオーバーライドと驚くべき方法で相互作用する。 アンカーと参照マップの両方が同じキーを定義している場合、参照マップの値が勝つ:

defaults: &defaults
  retries: 3
  timeout: 30

production:
  <<: *defaults
  retries: 10  # これが勝つ

つまりproduction.retriesは10であり、3ではない。これは期待される動作だが、「最後のものが勝つ」または「最初のものが勝つ」を順序に基づいて期待する人々をひっかける。

マージされたマップのキーは削除できない。 defaultsにlegacy_setting: trueキーがあり、productionで「解除」したい場合、それはできない。マージはキーを追加するだけで、決して削除しない。回避策:アンカーにそのキーを含めない。

アンカーは自身を参照できない。 自己参照アンカーはサイクルを生む。ほとんどのパーサーはこれを検出しエラーをスローする。「再帰的アンカー」エラーが出たら、それを含むアンカーを指し戻すエイリアスを探す。

アンカーとJSONは相容れない。 JSONにはアンカーの概念がない。アンカーを持つYAMLをJSONに変換すると、アンカーは展開される(JSONが大きくなる)か削除される(JSONが小さくなる)。どちらにせよ、結果はYAMLより大きい。JSONバージョンが必要な場合、通常は異なる設定ソースが必要だ。

一部のリンターはアンカーに文句を言う。 yamllintはデフォルトでスタイル上の理由からアンカーを無効にしている(anchors: disable)。アンカーを使っている場合、リンターを設定するか警告を受け入れる必要がある。アンカーを使うチームのほとんどは、リンとの摩擦に値すると考えている。

アンカーはパースされたオブジェクトグラフで機能し、テキストではない。 yqなどのツールでキーをアルファベット順にソートしてから再シリアライズすると、アンカーは可視キー順ではなく参照によって保持される。出力は正しいが、見た目は驚くことがある — アンカーが1箇所に表示され、エイリアスが別の場所にあり、同じオブジェクトを参照している。

設定でアンカーを検証する

アンカーが機能していることを確認する最速の方法は、YAMLを它们を解決するパーサーで読み込み、結果を表示することだ。DevSpeedToolsのYAMLバリデーターは解決されたオブジェクトグラフを表示する — アンカーが正しく配線されていれば、すべての場所で同じ値が見える。

より詳細な検査には、YAML統計ツールが一意キーと重複キーの合計数を示し、「アンカーが実際に重複を解消しているか」の良い指標になる。

インタラクティブなエディター体験には、Red Hat YAML拡張機能付きVS Codeがアンカーをホバーで解決し、各エイリアスがどこを指しているかを表示する。

まとめ

アンカーはYAML版の変数だ。パース時に機能し、シリアライズ時ではない。因此、書いたファイルにはアンカーが1回、参照が多くの場所に含まれる。パーサーは它们を同じ値に展開する。

共有デフォルトに使おう。ドキュメント間で状態を共有しようとするな。JSON変換が它们を保持すると期待するな。そして迷ったら、ファイルをバリデーターで実行して、展開が意図と一致することを確認しよう — 黙って間違った値を生成するアンカーは、本番にリリースされ、1年間そこに住む種類のバグだ。