C.W.K.
Stream
Lesson 06 of 08 · published

Anchors & Aliases — DRY YAML

~12 min · yaml, anchors, aliases, merge-keys

Level 0Plaintext
0 XP0/64 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Define once with &anchor, reuse with *alias

YAML supports anchors — give a node a name with &name — and aliases — reference it later with *name. The parsed result reuses the same node value, so two anchors-of-the-same-thing produce one logical value (or two copies, depending on the parser's deep-copy policy).

Merge keys (<<:)

Merge keys are a YAML 1.1 extension: <<: *base merges all keys from an anchored map into the current map, with the current map's keys overriding. This is how docker-compose and CI configs share base configuration without duplication.

Heads-up: merge keys are not in YAML 1.2 spec, but PyYAML, ruamel, js-yaml, and most working tools still support them. Treat as 'works almost everywhere; check your parser before relying.'

When to reach for anchors

Two or more nodes that should stay in sync. Without anchors, you have two places to update; with anchors, you have one source of truth. The cost is one extra layer of indirection at read time — worth it once you have repetition.

Principle: anchors and aliases are the YAML equivalent of variables. They make repeated configuration maintainable. Overuse them and the file becomes hard to read; underuse them and you maintain three copies of the same env-var block. Aim for 'used three times or more = anchor it.'

Code

Anchor + alias for repeated values·yaml
default_timeout: &timeout 30

endpoints:
  - name: search
    timeout: *timeout
  - name: index
    timeout: *timeout
  - name: admin
    timeout: *timeout
Merge keys for shared base configs·yaml
base_service: &base
  image: ghcr.io/cwk/api:1.0
  restart: unless-stopped
  environment:
    LOG_LEVEL: info

services:
  api:
    <<: *base
    ports: ["8000:8000"]
  worker:
    <<: *base
    command: ["python", "worker.py"]
  admin:
    <<: *base
    ports: ["8001:8001"]
    environment:
      LOG_LEVEL: debug   # overrides base
Anchor on a list element·yaml
shared_env: &shared_env
  - name: TZ
    value: Asia/Seoul
  - name: LOG_LEVEL
    value: info

containers:
  - name: api
    env: *shared_env
  - name: worker
    env: *shared_env

External links

Exercise

Take a docker-compose.yaml that has multiple services with overlapping config. Extract the shared bits into an anchor with <<: *base. Run docker compose config to confirm the parsed output is unchanged. Internalize: anchors are refactoring for YAML.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.