YAML Anchors and Aliases: Reuse Config Without Copy-Paste Drift
YAML anchors and aliases let you define a block once and reuse it across a file, eliminating copy-paste drift. Here's how they work, with a tested pattern and the trade-offs.
03 May 2026, 14:05 UTC

The duplication problem hiding in your YAML
Most long YAML files have the same disease: the same block of keys pasted three, five, ten times. A database connection block repeated across services. Identical resource limits copied into every container in a Kubernetes manifest. It works until someone updates one copy and forgets the others, and now staging and production quietly disagree.
YAML has a built-in fix that many people never use: anchors and aliases. An anchor names a node once; an alias reuses it anywhere else in the document. One definition, many references, zero drift.
How anchors and aliases work
An anchor is written with &name and attached to any node — a scalar, a list, or a whole mapping. An alias, *name, inserts that exact node wherever it appears. When the parser loads the document, every alias resolves to the anchored content.
defaults: &defaults
retries: 3
timeout: 30s
log_level: info
service-a:
<<: *defaults
port: 8080
service-b:
<<: *defaults
port: 9090The << here is the merge key: it merges the aliased mapping into the current one, so service-a ends up with retries, timeout, log_level, and its own port. Keys defined directly in the service override merged ones, which gives you a clean defaults-plus-overrides pattern. Note that the merge key is a YAML 1.1 convention that most mainstream parsers still honor, but it is not part of the core YAML 1.2 spec — plain aliases without << are universally safe.
A worked example: shared config across services
Say you run two workers that talk to the same database. Instead of duplicating the connection block, anchor it:
db: &db
host: postgres.internal
port: 5432
pool_size: 10
services:
ingest:
database: *db
queue: raw-events
reporter:
database: *db
schedule: "0 * * * *"You can verify the behavior with Python and ruamel.yaml (install with pip install ruamel.yaml; run in any environment with Python 3):
from ruamel.yaml import YAML
yaml = YAML(typ="safe")
with open("config.yaml") as f:
cfg = yaml.load(f)
assert cfg["services"]["ingest"]["database"] == cfg["services"]["reporter"]["database"]
assert cfg["services"]["ingest"]["database"]["host"] == "postgres.internal"Both services resolve to the same values. Change the anchor once — say, bump pool_size to 20 — re-parse, and both services pick it up. That is the entire payoff: a single source of truth inside the file. Run yamllint config.yaml as a syntax sanity check before committing.
The trade-offs worth knowing
Anchors are not free. Three limitations matter in practice:
- Hidden propagation. A change to an anchor silently affects every alias. In a large file, it can be hard to see who consumes a given anchor, so a "local" edit becomes a global one. Keep anchors near the top of the file and name them descriptively (
&db-prod, not&x). - Scope is one document. Anchors do not cross file boundaries. If you need reuse across files, you need templating (Helm, Kustomize, ytt) instead — anchors only deduplicate within a document.
- Parser support. Modern parsers (libyaml, PyYAML, ruamel.yaml, SnakeYAML, Go's yaml.v3) handle anchors and aliases fine, but some minimal or hand-rolled parsers do not. If your YAML is consumed by tooling you don't control, test a small anchored file through the real pipeline before committing to the pattern.
Also worth knowing: many parsers resolve aliases into separate copies of the data, so mutating one resolved node in your program may not mutate the others, even though they parsed identically. Treat anchors as a file-level authoring feature, not a runtime sharing mechanism.
When to reach for them
Use anchors when the same block appears more than twice in one file and the copies must stay identical — shared environment variables, repeated resource limits, common retry policies. Skip them when blocks only happen to look similar today but will diverge tomorrow; aliasing those creates coupling you'll regret.
The actionable test: open your longest YAML file, search for a repeated key, and count the copies. If the answer is three or more and they must match, define one anchor, alias the rest, and verify with a quick parse-and-assert script like the one above. Your future self — the one updating the database host at 2 a.m. — will thank you.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.