The DRY Principle (Don't Repeat Yourself)
In large DevOps files (like a Docker Compose with 20 services or a GitLab CI file with 50 jobs), you will often find yourself copy-pasting the same configuration blocks over and over again.
If you need to change the logging size from 10m to 20m, you have to manually edit 50 different lines. This is prone to error and "Configuration Drift."
YAML solves this natively using Anchors and Aliases.
1. Creating an Anchor (&)
An Anchor acts like a variable definition. You prefix a block of data with the ampersand (&) and give it a name.
# Define a common configuration block
default_settings: &base_app
image: alpine:latest
environment:
ENV: production
restart: always2. Using an Alias (*)
To reuse that block later, you use an Alias by prefixing the anchor name with an asterisk (*).
services:
web:
<<: *base_app # We'll explain <<: in a moment
ports:
- "80:80"
worker:
<<: *base_app
command: ["./worker"]3. The Merge Key (<<:)
In the example above, we used the special characters <<:. This is the Merge Key.
By default, an Alias (*base_app) replaces the entire value of a key.
By using <<: *base_app, you are telling YAML: "Take all the key-value pairs from the anchor and merge them into THIS object, but keep my existing unique keys (like ports and command) as well."
Overriding Values
The Merge Key also allows you to override specific values from the anchor.
api_service:
<<: *base_app
environment:
ENV: staging # This overrides the "production" value in the anchor!Where you will see this
- GitLab CI: Using
.hidden keys (e.g.,.setup_python: &setup) to define shared test scripts that you inject into every job. - Docker Compose: Defining a
&default-dbconfig that you use for both Postgres and Redis services. - Home Assistant: Managing thousands of smart home sensors with shared icon/color schemes.
Mastering Anchors and Aliases is the difference between a "Junior" and a "Senior" level of system configuration management.