YAML Anchors and Aliases
Updated
Anchors and aliases are YAML's built-in mechanism for reuse. Mark a value
with &name once, then reference it anywhere in the same
document with *name. Combined with the merge key
<<, they let you define defaults in one place and
override only what changes, which is exactly what large Docker Compose
and CI files need.
Anchors and aliases
defaults: &defaults
timeout: 30
retries: 3
service_a:
settings: *defaults
service_b:
settings: *defaults
Both services get the same settings mapping. Change the
anchored block and every alias follows. An anchor can be attached to any
node: a mapping, a list, or a single scalar.
region: ®ion us-east-1
primary_region: *region
backup_region: *region Merge keys: <<
An alias replaces a whole value. To inherit keys and then override some, use the merge key:
base: &base
image: node:20
restart: unless-stopped
environment:
NODE_ENV: production
web:
<<: *base
ports:
- "3000:3000"
worker:
<<: *base
command: npm run worker
restart: "no" # overrides the merged value
Keys written directly in web and worker take
precedence over the merged ones. Note that the merge is shallow:
environment is replaced as a whole if you redefine it, not
merged key by key.
Merging several anchors at once is allowed with a list; earlier entries win on conflicts:
prod:
<<: [*base, *prod_overrides] Real-world examples
Docker Compose
x-logging: &default-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
api:
image: myorg/api:1.4.2
logging: *default-logging
db:
image: postgres:16
logging: *default-logging
Top-level keys starting with x- are extension fields that
Compose ignores, making them the conventional home for anchored blocks.
GitLab CI
.node_job: &node_job
image: node:20
before_script:
- npm ci
test:
<<: *node_job
script: npm test
lint:
<<: *node_job
script: npm run lint
Keys beginning with a dot are hidden jobs in GitLab CI, so they serve as
templates without running. GitLab also offers extends:, which
does a deep merge and works across included files, so prefer it for
anything complex.
Rules and limitations
- An anchor must be defined before it is referenced, reading top to bottom.
- Anchors are scoped to one document. They do not cross
---boundaries or files. - Anchor names may contain letters, digits,
-, and_. Spaces and most punctuation are not allowed. - Redefining an anchor name later in the document is legal; aliases after that point use the new value.
- The merge key
<<only works on mappings. You cannot merge lists. - Not every consumer supports anchors. GitHub Actions rejects them; some strict JSON-schema-based tools expand them but then complain about the duplicated content.
Debugging anchors
The easiest way to see what an alias actually produces is to expand it.
Paste the file into the YAML to JSON converter
or the YAML parser; both resolve every alias
and merge key so you can read the final structure. If the file fails to
parse with "unidentified alias", the *name has a typo or is
used before its &name.
Frequently asked questions
What is an anchor in YAML?
An anchor is a label attached to a node with &name. Elsewhere in the same document, *name (an alias) refers back to that node, so the value is reused without being copied.
What does << mean in YAML?
<< is the merge key. <<: *base copies every key from the anchored mapping into the current mapping, and keys defined locally override the merged ones. It is not part of YAML 1.2 core but is supported by most parsers, including PyYAML, js-yaml, Docker Compose, and GitLab CI.
Can I use an anchor from another file?
No. Anchors are scoped to a single document. Even within one file, an anchor defined in one --- separated document is not visible in the next.
Do anchors survive conversion to JSON?
No. JSON has no reference concept, so aliases are expanded into copies. The data is identical but the file gets longer. See the YAML to JSON converter.
Does Kubernetes support YAML anchors?
kubectl parses anchors and aliases within a single document. Helm does too, but only inside one template. GitHub Actions does not support anchors at all and will reject the workflow.