X Xerobit

YAML Anchors and Aliases — Reusing Values with & and *

YAML anchors (&) define a reusable value; aliases (*) reference it. This eliminates repetition in YAML configuration. Here's how to use anchors, aliases, and merge keys (<<) in...

Mian Ali Khalid · · 5 min read
Use the tool
YAML ↔ JSON Converter
Convert between YAML and JSON formats with full fidelity.
Open YAML ↔ JSON Converter →

YAML anchors (&) mark a value for reuse; aliases (*) paste that value back in. This prevents duplication across large YAML files — useful in Docker Compose, Kubernetes, and CI/CD configurations.

Use the YAML to JSON Converter to validate and convert YAML documents.

Basic anchor and alias syntax

# Define an anchor with & followed by a name:
default_timeout: &timeout 30

# Reference it with *:
service_a:
  timeout: *timeout   # becomes 30

service_b:
  timeout: *timeout   # also 30

The anchor name can be anything — it’s just a label. The anchor value is copied inline wherever the alias appears.

Anchoring scalar values

# String anchor:
default_image: &image "node:20-alpine"

web:
  image: *image

worker:
  image: *image

# Number anchor:
replicas: &default_replicas 3

frontend:
  replicas: *default_replicas

api:
  replicas: *default_replicas

Anchoring mappings (objects)

You can anchor entire objects:

defaults: &defaults
  restart: unless-stopped
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "3"

services:
  web:
    image: nginx:alpine
    <<: *defaults      # merge the defaults object in

  api:
    image: node:20-alpine
    <<: *defaults      # same defaults

The << key is the YAML merge key — it merges mapping contents from the alias into the current mapping.

Merge key (<<) in depth

base_config: &base
  host: localhost
  port: 5432
  ssl: true

# Override some fields after merge:
production:
  <<: *base
  host: prod-db.example.com   # overrides base host
  ssl: true                    # same as base

staging:
  <<: *base
  host: staging-db.example.com
  port: 5433                   # overrides base port

The merged keys from *base fill in as defaults — keys defined in the current mapping take precedence.

Multiple merge sources

You can merge from multiple anchors:

defaults: &defaults
  restart: unless-stopped
  network: app-network

logging: &logging
  logging:
    driver: json-file

service:
  <<: [*defaults, *logging]   # merge both
  image: myapp:latest

Docker Compose example

x-common: &common
  restart: unless-stopped
  env_file: .env
  networks:
    - app-net

x-logging: &logging
  logging:
    driver: json-file
    options:
      max-size: "50m"
      max-file: "5"

services:
  web:
    <<: [*common, *logging]
    image: nginx:alpine
    ports:
      - "80:80"

  api:
    <<: [*common, *logging]
    image: node:20-alpine
    ports:
      - "3000:3000"
    depends_on:
      - db

  db:
    <<: *common
    image: postgres:16-alpine
    volumes:
      - pg-data:/var/lib/postgresql/data

networks:
  app-net:

volumes:
  pg-data:

Without anchors, the restart, env_file, networks, and logging blocks would be repeated in every service.

GitHub Actions example

defaults: &defaults
  runs-on: ubuntu-latest
  timeout-minutes: 30

jobs:
  test:
    <<: *defaults
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  build:
    <<: *defaults
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

  deploy:
    <<: *defaults
    needs: [test, build]
    steps:
      - run: npm run deploy

Anchoring sequences (arrays)

common_tags: &tags
  - production
  - web
  - monitored

service_a:
  tags: *tags

service_b:
  tags: *tags

Note: you can’t easily merge sequences with << (that’s for mappings only). If you need to extend a sequence, you have to use a different approach or concatenate manually.

Anchors in Kubernetes

common_labels: &labels
  app: myapp
  env: production
  team: platform

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

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  labels:
    <<: *labels
spec:
  template:
    spec:
      containers:
        - name: api
          image: api:latest
          resources:
            <<: *resources
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: worker
  labels:
    <<: *labels
spec:
  template:
    spec:
      containers:
        - name: worker
          image: worker:latest
          resources:
            <<: *resources

YAML anchors in JSON conversion

Anchors are a YAML-only feature — they’re resolved when parsing:

default: &val 42
a: *val
b: *val

Converts to JSON as:

{
  "default": 42,
  "a": 42,
  "b": 42
}

The anchor names disappear in the output — they’re purely a YAML authoring convenience.

Limitations

  • Anchors are document-scoped — you can’t reference an anchor from another YAML file
  • Some YAML parsers have strict anchor limits for security (preventing billion-laughs-style YAML bombs)
  • Aliases are copied by value, not reference — modifying one doesn’t affect others
  • The << merge key is from the YAML 1.1 spec; in YAML 1.2 (stricter), it’s implementation-defined

Related posts

Related tool

YAML ↔ JSON Converter

Convert between YAML and JSON formats with full fidelity.

Written by Mian Ali Khalid. Part of the Data & Format pillar.