YAML Anchors and Aliases Explained: DRY Configuration
The Repetition Problem in YAML
Configuration files often contain repeated blocks — the same database credentials across environments, identical build steps for multiple jobs, or shared container settings across services. Copy-pasting these blocks works until one value changes and you forget to update the other three copies.
YAML anchors and aliases solve this by letting you define a block once and reference it elsewhere. Changes propagate to every reference automatically.
Anchors: Define a Reusable Block
An anchor marks a node with a name using &:
defaults: &defaults
timeout: 30
retries: 3
log_level: info
The &defaults anchor attaches the name defaults to that mapping. The node still appears in the final data — anchoring doesn't remove it.
Aliases: Reference an Anchored Block
An alias references an anchored node using *:
defaults: &defaults
timeout: 30
retries: 3
log_level: info
production:
<<: *defaults
log_level: warning
database: prod-db
staging:
<<: *defaults
database: staging-db
The *defaults alias copies the anchored mapping. Combined with the merge key <<, it merges the anchored keys into the current mapping.
The Merge Key (<<)
The merge key << inserts all keys from an aliased mapping into the current mapping. Keys defined explicitly in the current mapping override merged keys:
production:
<<: *defaults # Merges timeout, retries, log_level
log_level: warning # Overrides the merged log_level
database: prod-db # Adds a new key
Result after parsing:
production:
timeout: 30
retries: 3
log_level: warning # Overridden
database: prod-db # Added
Merging Multiple Anchors
You can merge from multiple anchors:
base: &base
image: node:20
working_dir: /app
cache: &cache
cache:
paths:
- node_modules/
build:
<<: [*base, *cache]
script: npm run build
Later anchors override keys from earlier ones when both define the same key.
Anchors Without Merging
Anchors work with any YAML node type, not just mappings:
Anchored Sequences
common_steps: &common_steps
- checkout
- install dependencies
deploy_production:
steps:
- *common_steps
- deploy to production
Note: *common_steps as a list item creates a nested list. To flatten it, structure your anchors differently or use merge keys.
Anchored Scalars
api_version: &apiVersion v1
service1:
apiVersion: *apiVersion
service2:
apiVersion: *apiVersion
Useful for values that appear in many places and might change together — like API versions or image tags.
Real-World Patterns
GitHub Actions
defaults: &_step_defaults
working-directory: ./app
install: &install
<<: *step_defaults
run: npm ci
lint:
<<: *step_defaults
needs: install
run: npm run lint
test:
<<: *step_defaults
needs: install
run: npm test
Kubernetes
common_labels: &common_labels
app.kubernetes.io/part-of: myapp
app.kubernetes.io/managed-by: helm
deployment:
metadata:
labels:
<<: *common_labels
app.kubernetes.io/component: api
Docker Compose
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
services:
web:
<<: *common
image: myapp-web
ports:
- "3000:3000"
worker:
<<: *common
image: myapp-worker
The x- prefix is a Docker Compose convention for extension fields — they don't appear in the final config but serve as anchor containers.
Limitations
- No circular references: An alias cannot reference an anchor defined within the same node it merges into.
- Merge key only works with mappings: You can't use
<<with sequences or scalars. - Parser support varies: Some YAML parsers (especially older ones) don't support merge keys.
PyYAMLsupports them;js-yamlsupports them; Go'sgopkg.in/yaml.v2supports them. - No partial overrides of nested mappings: The merge key operates at the top level. If you merge a mapping with a nested
database:key, you can't override justdatabase.host— you must override the entiredatabase:block.
Key Takeaways
- Anchors (
&name) mark a node for reuse; aliases (*name) reference it - The merge key (
<<) inserts keys from an anchored mapping, with local keys taking precedence - Anchors work with any node type: mappings, sequences, and scalars
- Use extension fields (
x-) in Docker Compose to hold anchors without polluting the output - Merge key limitations: no nested partial overrides, mappings only, parser support varies
- Anchors and aliases are a parsing-level feature — the consuming application sees only the resolved data
Related Guides
Try It Yourself
Convert between JSON and YAML instantly with our free JSON-YAML Converter. Paste your config, see the anchors resolved, and switch formats in one click.