JSONYAMify

Home / Blog / YAML Anchors & Aliases

YAML Anchors & Aliases: Reuse Konfigurasi Tanpa Duplikasi

Oleh Andi Putra Ogie · Update: Juli 2026 · 9 menit baca

Pernah punya file docker-compose.yml dengan 5 service yang semuanya butuh konfigurasi logging, network, atau environment variable yang sama persis? Copy-paste blok yang sama berkali-kali memang jalan, tapi begitu ada perubahan, kamu harus edit di banyak tempat — dan rawan lupa satu. YAML punya fitur bawaan untuk masalah ini: anchors dan aliases.

Fitur ini jarang diajarkan di tutorial YAML dasar, padahal sangat berguna terutama untuk file konfigurasi besar seperti Docker Compose, Kubernetes manifest, atau GitHub Actions workflow.

Apa itu Anchor dan Alias?

Anchor (ditandai simbol &) adalah cara memberi "nama" pada sebuah blok atau nilai YAML supaya bisa dipakai ulang di tempat lain. Alias (ditandai simbol *) adalah cara memanggil kembali blok yang sudah diberi anchor tersebut. Analoginya mirip variabel di bahasa pemrograman: anchor itu seperti mendeklarasikan variabel, alias itu seperti memakai variabel tersebut.

Selain menghemat baris kode, anchor dan alias juga mengurangi risiko human error — kalau kamu harus mengubah satu nilai yang muncul di 10 tempat berbeda, cukup ubah di satu anchor dan semua alias otomatis ikut berubah saat file di-parse ulang. Ini jauh lebih aman dibanding mengandalkan find-and-replace manual yang rawan salah satu tempat terlewat.

Contoh Paling Sederhana

defaults: &defaults
  adapter: postgres
  host: localhost

development:
  <<: *defaults
  database: myapp_development

test:
  <<: *defaults
  database: myapp_test

Di contoh ini, &defaults menandai blok adapter dan host sebagai anchor bernama defaults. Lalu di bagian development dan test, <<: *defaults berarti "gabungkan (merge) semua isi anchor defaults ke sini". Hasil setelah di-parse, development akan punya adapter: postgres, host: localhost, dan database: myapp_development — tiga field sekaligus, padahal cuma menulis satu baris.

Merge Key: <<

Simbol << disebut merge key. Fungsinya menggabungkan isi map dari anchor ke dalam map saat ini. Kalau ada key yang sama di kedua map, key yang didefinisikan secara eksplisit di map saat ini akan menang (override), bukan yang dari anchor. Contoh:

base: &base
  timeout: 30
  retries: 3

service_a:
  <<: *base
  timeout: 60   # override, jadi 60 bukan 30

Hasil service_a akan punya timeout: 60 (override) dan retries: 3 (warisan dari base) — kombinasi keduanya.

Alias Tanpa Merge: Reuse Nilai Sederhana

Anchor dan alias tidak harus dipakai dengan merge key. Kamu juga bisa memakainya untuk nilai tunggal (string, number, list):

company: &company_name "PT Nusantara Digital"

report_title: *company_name
email_signature: *company_name

Di sini, report_title dan email_signature akan sama-sama bernilai "PT Nusantara Digital" — kalau nama perusahaan berubah, cukup edit satu tempat di anchor.

Contoh Nyata: Docker Compose

Ini kasus penggunaan paling umum di dunia nyata. Bayangkan beberapa service yang semuanya butuh setting logging yang sama:

x-logging: &default-logging
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

services:
  web:
    image: myapp/web
    logging: *default-logging
  worker:
    image: myapp/worker
    logging: *default-logging
  scheduler:
    image: myapp/scheduler
    logging: *default-logging

Perhatikan key x-logging di atas — awalan x- adalah konvensi Docker Compose untuk field "extension" yang tidak divalidasi sebagai service asli, cocok dipakai khusus sebagai tempat menaruh anchor supaya tidak bentrok dengan schema Compose.

Contoh Nyata: GitHub Actions

Anchor juga sering dipakai di workflow CI/CD untuk menghindari duplikasi step atau environment yang sama di banyak job:

env: &common_env
  NODE_ENV: production
  API_URL: https://api.example.com

jobs:
  build:
    env: *common_env
    steps:
      - run: npm run build
  test:
    env: *common_env
    steps:
      - run: npm test

Anchor untuk List (Array)

Anchor tidak terbatas pada map/object, bisa juga dipakai untuk list:

common_ports: &ports
  - "80:80"
  - "443:443"

service_a:
  ports: *ports

service_b:
  ports: *ports

Batasan dan Hal yang Perlu Diperhatikan

Kapan Sebaiknya Pakai Anchor & Alias?

Fitur ini paling berguna kalau kamu punya konfigurasi berulang dalam jumlah banyak — misalnya lebih dari 3 service dengan setting yang identik, atau matrix testing dengan environment variable yang sama. Untuk file kecil dengan 1-2 pengulangan saja, terkadang lebih mudah dibaca kalau ditulis eksplisit tanpa anchor, karena anchor bisa membuat file agak sulit dibaca bagi orang yang belum familiar dengan sintaksnya.

Anchor Bersarang dan Kombinasi Beberapa Anchor

Anchor bisa dipakai berlapis — sebuah blok yang sudah memakai alias tetap bisa diberi anchor baru lagi untuk dipakai ulang lebih jauh. Ini berguna kalau kamu punya hierarki konfigurasi bertingkat, misalnya base config, lalu regional config yang mewarisi base, lalu environment-specific config yang mewarisi regional:

base: &base
  timeout: 30

regional_id: ®ional_id
  <<: *base
  region: "id"
  currency: "IDR"

production_id:
  <<: *regional_id
  debug: false

Beberapa parser YAML juga mendukung multiple merge key dalam satu map, ditulis sebagai list alias:

combined:
  <<: [*base, *regional_id]

Perlu diingat, dukungan multiple merge key ini tidak universal di semua parser, jadi selalu cek dulu di library YAML yang kamu pakai (misalnya PyYAML, js-yaml, atau SnakeYAML) sebelum mengandalkannya di production.

Anchor vs Referensi Eksternal (Include File)

Penting dibedakan: anchor dan alias hanya bekerja di dalam satu file YAML yang sama (atau dalam satu multi-document stream yang dipisah ---, tergantung parser). Anchor tidak bisa dipakai untuk "include" file YAML lain seperti import di bahasa pemrograman. Kalau kamu butuh reuse konfigurasi lintas file, itu fitur terpisah yang biasanya disediakan oleh tool di atas YAML (misalnya Helm {{ include }} di Kubernetes, atau fitur <<: !include non-standar di beberapa custom loader), bukan bagian dari spesifikasi YAML itu sendiri.

💡 File YAML dengan banyak anchor dan alias kadang jadi susah dibaca kalau formatnya berantakan. Gunakan JSONYAMify untuk memformat ulang YAML kamu supaya indentasi konsisten dan mudah ditelusuri, atau konversi ke JSON untuk melihat hasil akhir setelah merge secara visual.
🔧 Rapikan YAML Kamu di JSONYAMify

YAML Anchors & Aliases: Reuse Configuration Without Duplication

By Andi Putra Ogie · Updated: July 2026 · 9 min read

Ever had a docker-compose.yml with 5 services that all need the exact same logging, network, or environment variable configuration? Copy-pasting the same block over and over works, but the moment something changes, you have to edit it in multiple places — and it's easy to miss one. YAML has a built-in feature for exactly this problem: anchors and aliases.

This feature is rarely covered in basic YAML tutorials, even though it's extremely useful, especially for large config files like Docker Compose, Kubernetes manifests, or GitHub Actions workflows.

What Are Anchors and Aliases?

An anchor (marked with &) is a way to "name" a YAML block or value so it can be reused elsewhere. An alias (marked with *) is how you call back that anchored block. Think of it like variables in a programming language: an anchor is like declaring a variable, and an alias is like using that variable.

The Simplest Example

defaults: &defaults
  adapter: postgres
  host: localhost

development:
  <<: *defaults
  database: myapp_development

test:
  <<: *defaults
  database: myapp_test

In this example, &defaults marks the adapter and host block as an anchor named defaults. Then in the development and test sections, <<: *defaults means "merge everything from the defaults anchor in here." After parsing, development ends up with adapter: postgres, host: localhost, and database: myapp_development — three fields from writing just one line.

The Merge Key: <<

The << symbol is called the merge key. Its job is to merge the map contents from an anchor into the current map. If the same key exists in both maps, the one explicitly defined in the current map wins (it overrides the anchor's value). Example:

base: &base
  timeout: 30
  retries: 3

service_a:
  <<: *base
  timeout: 60   # overridden, becomes 60 instead of 30

The resulting service_a ends up with timeout: 60 (overridden) and retries: 3 (inherited from base) — a combination of both.

Aliases Without Merging: Reusing Simple Values

Anchors and aliases don't have to be used with a merge key. You can also use them for a single value (string, number, list):

company: &company_name "PT Nusantara Digital"

report_title: *company_name
email_signature: *company_name

Here, both report_title and email_signature will equal "PT Nusantara Digital" — if the company name ever changes, you only need to edit it in one place, the anchor.

Real-World Example: Docker Compose

This is the most common real-world use case. Imagine several services that all need the same logging settings:

x-logging: &default-logging
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

services:
  web:
    image: myapp/web
    logging: *default-logging
  worker:
    image: myapp/worker
    logging: *default-logging
  scheduler:
    image: myapp/scheduler
    logging: *default-logging

Notice the x-logging key above — the x- prefix is a Docker Compose convention for "extension" fields that aren't validated as an actual service, making it a good spot to place anchors without clashing with the Compose schema.

Real-World Example: GitHub Actions

Anchors are also commonly used in CI/CD workflows to avoid duplicating steps or the same environment across multiple jobs:

env: &common_env
  NODE_ENV: production
  API_URL: https://api.example.com

jobs:
  build:
    env: *common_env
    steps:
      - run: npm run build
  test:
    env: *common_env
    steps:
      - run: npm test

Anchors for Lists (Arrays)

Anchors aren't limited to maps/objects — they can be used for lists too:

common_ports: &ports
  - "80:80"
  - "443:443"

service_a:
  ports: *ports

service_b:
  ports: *ports

Limitations and Things to Watch Out For

When Should You Actually Use Anchors & Aliases?

This feature is most useful when you have a large amount of repeated configuration — for example, more than 3 services with identical settings, or a test matrix sharing the same environment variables. For small files with just 1-2 repetitions, it's sometimes easier to read if written out explicitly without anchors, since anchors can make a file harder to follow for people unfamiliar with the syntax.

Nested Anchors and Combining Multiple Anchors

Anchors can be layered — a block that already uses an alias can itself be given a new anchor for further reuse. This is handy when you have a tiered configuration hierarchy, e.g. a base config, then a regional config that inherits from base, then an environment-specific config that inherits from regional:

base: &base
  timeout: 30

regional_id: ®ional_id
  <<: *base
  region: "id"
  currency: "IDR"

production_id:
  <<: *regional_id
  debug: false

Some YAML parsers also support multiple merge keys in a single map, written as a list of aliases:

combined:
  <<: [*base, *regional_id]

Keep in mind this multiple merge key support isn't universal across all parsers, so always check the YAML library you're using (e.g. PyYAML, js-yaml, or SnakeYAML) before relying on it in production.

Anchors vs External References (File Includes)

It's important to distinguish: anchors and aliases only work within a single YAML file (or within one multi-document stream separated by ---, depending on the parser). Anchors cannot be used to "include" another YAML file the way import works in a programming language. If you need to reuse configuration across files, that's a separate feature usually provided by a tool layered on top of YAML (e.g. Helm's {{ include }} in Kubernetes, or a non-standard <<: !include in some custom loaders), not something part of the YAML spec itself.

💡 YAML files with lots of anchors and aliases can get hard to read if the formatting is messy. Use JSONYAMify to reformat your YAML with consistent indentation, or convert it to JSON to visually inspect the final result after merging.
🔧 Clean Up Your YAML on JSONYAMify