alltools.one
YAMLβ€’
2025-06-19
β€’
7 min
β€’
alltools.one Team
YAMLAnchorsAliasesDRYConfiguration

YAML Anchors and Aliases: DRY Configuration Patterns

Repeating the same configuration across multiple sections of a YAML file violates the DRY (Don't Repeat Yourself) principle and creates maintenance headaches. YAML anchors and aliases solve this by allowing you to define a value once and reference it multiple times.

Basic Syntax

Anchor (&): Marks a value for reuse Alias (*): References an anchored value

# Define an anchor
defaults: &default_settings
  timeout: 30
  retries: 3
  log_level: info

# Use aliases to reference it
development:
  <<: *default_settings
  log_level: debug

production:
  <<: *default_settings
  retries: 5

The << merge key incorporates all key-value pairs from the referenced anchor. Properties defined after the merge override the anchored values.

Result after resolution:

development:
  timeout: 30
  retries: 3
  log_level: debug  # overridden

production:
  timeout: 30
  retries: 5        # overridden
  log_level: info

Anchor Types

Scalar Anchors

Reuse a single value:

max_connections: &max_conn 100

database:
  pool_size: *max_conn
cache:
  pool_size: *max_conn

Sequence Anchors

Reuse entire lists:

common_ports: &ports
  - 80
  - 443

web_server:
  ports: *ports
load_balancer:
  ports: *ports

Mapping Anchors

Reuse entire objects (the most common pattern):

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

services:
  api:
    logging: *log_config
  worker:
    logging: *log_config

The Merge Key (<<)

The merge key has specific behavior:

  1. It copies all key-value pairs from the referenced mapping
  2. Explicitly set keys take priority over merged keys
  3. Multiple merges are processed in order (first wins for conflicts)
# Multiple merges
base: &base
  a: 1
  b: 2

extra: &extra
  b: 3
  c: 4

combined:
  <<: [*base, *extra]
  # Result: a=1, b=2 (base wins), c=4

Real-World Examples

Docker Compose

x-common: &common
  restart: unless-stopped
  networks:
    - app-network
  logging:
    driver: json-file
    options:
      max-size: "10m"

services:
  api:
    <<: *common
    image: myapp/api:latest
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://db:5432/myapp

  worker:
    <<: *common
    image: myapp/worker:latest
    environment:
      QUEUE_URL: redis://cache:6379

  scheduler:
    <<: *common
    image: myapp/scheduler:latest

Docker Compose uses the x- prefix convention for extension fields that hold anchors. See our YAML for Docker Compose guide for more patterns.

GitHub Actions

jobs:
  test:
    runs-on: ubuntu-latest
    env: &common_env
      NODE_VERSION: '20'
      CI: true
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: npm test

  build:
    runs-on: ubuntu-latest
    needs: test
    env:
      <<: *common_env
      BUILD_TARGET: production
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

Kubernetes

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: app
          resources: &resources
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
        - name: sidecar
          resources: *resources  # Same resource limits

Limitations and Pitfalls

1. No Cross-File References

Anchors only work within a single YAML file. You cannot reference an anchor defined in another file. For cross-file reuse, use templating tools like Helm, Jsonnet, or Kustomize.

2. No Partial Overrides in Sequences

You cannot merge and partially override a list β€” you replace the entire list:

base_ports: &ports
  - 80
  - 443

service:
  ports: *ports  # You get exactly [80, 443]
  # Cannot add port 8080 to this list via merge

Workaround: Define the extended list separately.

3. Ordering Matters

Anchors must be defined before they are referenced:

# WRONG - alias before anchor
service:
  settings: *defaults

defaults: &defaults
  timeout: 30

# CORRECT - anchor before alias
defaults: &defaults
  timeout: 30

service:
  settings: *defaults

4. Not All Tools Support Merge Keys

The << merge key is not part of the core YAML specification β€” it is a type-specific extension. Most popular YAML parsers support it, but some strict parsers may not.

Validate your YAML anchor usage with our YAML Validator.

FAQ

Are anchors preserved when converting YAML to JSON?

No. When YAML is parsed, anchors and aliases are resolved into their values. The resulting JSON will have the values expanded inline. This means converting to JSON and back will lose the DRY structure. The anchors exist only in the YAML source format.

Can I use anchors with complex nested overrides?

The merge key (<<) only performs a shallow merge β€” it copies top-level keys from the anchored mapping. Nested objects are replaced entirely, not deep-merged. For deep merge behavior, you need a tool-specific solution (Helm's merge function, custom YAML processors).

Related Resources

Published on 2025-06-19
YAML Anchors and Aliases: DRY Configuration Patterns | alltools.one