YAML Merge Keys
Repeating the same settings in many places wastes time and invites mistakes. A merge key copies the contents of one mapping into another. Combined with an anchor, it lets you write shared settings once and reuse them everywhere. Changes to the shared block flow through to every copy automatically.
A Quick Reminder About Anchors
An anchor labels a block with an ampersand. Aliases refer back to that label with an asterisk. A merge key takes the aliased mapping and pours its keys into the current one.
The Merge Syntax
The merge key is written as two angle brackets followed by a colon: <<. The value is an alias.
defaults: &defaults
color: blue
size: medium
stock: 10
shirt:
<<: *defaults
name: Polo
hat:
<<: *defaults
name: CapBoth shirt and hat receive color, size, and stock from the defaults block. Each also keeps its own name.
What the Parser Builds
defaults ----+
color: blue |
size: medium +--> copied into --> shirt: color, size, stock, name: Polo
stock: 10 |
+--> copied into --> hat: color, size, stock, name: Cap
The parser expands every merge before your program sees the data. The final result contains full, separate mappings with no merge keys left over.
Overriding Merged Values
Keys written directly in the mapping win over merged keys. Use that rule to adjust a single setting.
jacket:
<<: *defaults
name: Parka
color: black
stock: 3The jacket keeps the size from the defaults and replaces the color and stock. This approach describes a family of similar items with minimal typing.
Merging Several Sources
A list of aliases merges more than one mapping:
base: &base
restart: always
network: main
logging: &logging
log_driver: json-file
log_level: info
web:
<<: [*base, *logging]
image: nginxWhen two sources contain the same key, the one listed earlier takes priority. Put the most important source at the front of the list.
| Priority | Source |
|---|---|
| Highest | Keys written directly in the mapping |
| Next | First alias in the merge list |
| Lowest | Last alias in the merge list |
Where Merge Keys Work
The merge key comes from YAML 1.1 and sits outside the core YAML 1.2 specification. Most popular libraries support it, including PyYAML and the parsers inside Docker Compose, GitLab CI, and many other tools. A few strict parsers ignore it and treat << as an ordinary key.
- Test the feature in the exact tool you use.
- Read the tool documentation for merge support.
- Check that the final merged data looks correct by printing it.
Merging Shallow Only
A merge copies top-level keys only. Nested mappings do not combine automatically. A nested key in the local mapping replaces the whole nested block from the source.
base: &base
db:
host: localhost
port: 5432
prod:
<<: *base
db:
host: prod.example.comThe production mapping ends up with a db block holding only the host. The port from the base disappears. Remember this limit when you design layered settings.
Good Habits
- Name anchors by purpose, such as
defaultsorcommon. - Place anchor definitions near the top of the file.
- Keep merged blocks small and focused.
- Add a comment above each anchor explaining what it shares.
A Real-Life Comparison
A restaurant chain shares one base menu across every branch. A single branch adds a local dish and changes one price. The base menu plays the role of the anchor, and each branch file merges it and lists only the differences. Updating the base menu updates every branch at once.
Merge keys reward careful planning. A clear base block, short overrides, and honest comments keep large files readable.
