Using YAML Anchors and Aliases for DRY Configurations
YAML anchors (&) and aliases (*) let you define reusable blocks, avoiding duplication in configs. This guide explains how they work, shows a concrete example, and covers limits and common pitfalls.
05 Jul 2026, 14:13 UTC

Why Use Anchors?
When the same block of key/value pairs appears in several places—like a container image, port list, or resource limits—copy‑and‑paste quickly becomes error‑prone. YAML anchors (&name) let you declare a node once and reuse it later with an alias (*name). The merge key << (double‑less‑than) then injects that node into another mapping. This built‑in DRY mechanism works natively in Kubernetes manifests, CI pipelines, and many application configuration files.
How Anchors and Aliases Work
1. Anchor definition: Use & before a node name to store the node in the parser’s internal table. 2. Alias reference: Use *name to pull that stored node wherever you need it. 3. Merge key (<<): In YAML 1.1, the key << merges the referenced mapping into the current one, overriding only missing keys.
Below is a minimal example that demonstrates all three concepts.
# file: services.yaml
# Define a base service block once
base: &base
image: nginx:1.25
ports:
- 80
# Reuse the base for two services
serviceA:
<<: *base
replicas: 2
serviceB:
<<: *base
replicas: 1
When parsed, the resulting data structure is equivalent to:
{
"base": {"image": "nginx:1.25", "ports": [80]},
"serviceA": {"image": "nginx:1.25", "ports": [80], "replicas": 2},
"serviceB": {"image": "nginx:1.25", "ports": [80], "replicas": 1}
}
Concrete Verification Steps
- Validate with kubectl (Kubernetes): If this file is a manifest, run:
This will parse the file and report any syntax errors without applying changes.kubectl apply --dry-run=client -f services.yaml - Check object identity in Python: Anchors are shared objects. Loading the file with
PyYAMLand inspectingid()shows that*baserefers to the same mapping instance.
The twoimport yaml, pprint with open("services.yaml") as f: data = yaml.safe_load(f) print(id(data["base"]), id(data["serviceA"]["image"])) pprint.pprint(data)idvalues forimageshould match, indicating shared reference.
Limits and Compatibility
- YAML 1.1 vs 1.2: The merge key << is defined in YAML 1.1 and is optional in 1.2. Some parsers (e.g.,
yaml.safe_load) still support it, but others may reject it. If portability to 1.2‑only tools is required, consider duplicating the block or using templating instead. - No deep copy: An alias points to the same in‑memory node. Mutating the referenced node in one place will affect all aliases. In languages that preserve object identity, this can lead to subtle bugs.
- Scope rules: An anchor cannot be redefined in the same mapping or within the same level of nesting. Attempts to do so will raise a parsing error.
- Flow style restrictions: Many parsers disallow anchors in flow style (inline) mappings or sequences. Stick to block style for maximum compatibility.
Common Mistakes to Avoid
- Referencing an alias before its anchor is defined. YAML requires the anchor to appear earlier in the document.
- Creating circular references, e.g.,
a: &a [*a]. This causes parser errors or stack overflows. - Assuming the merge key works identically across all tools. Some Kubernetes versions silently ignore it, others error out.
- Confusing anchors with templating or environment variable substitution. Anchors are static; they do not evaluate expressions.
- Using anchors for large blocks that change frequently. Because aliases share the same object, frequent changes can lead to unintended side effects.
Practical Tip
When you need a small, repeatable block that will never change, anchors are a lightweight, parser‑native solution. For more complex, dynamic configurations, consider a templating engine (Helm, Jinja2) or a configuration language that supports loops and conditionals.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.