Skip to main content
Nick Marsceau

How To Use YAML Anchors

This week I learned about YAML anchors. A YAML anchor is a way to assign a name to a chunk of YAML, then reuse that chunk elsewhere in the document.


twins:
  Fred: &twinDetails
    hairColor: red
    lastName: Weasley
    mischievous: true
  George: *twinDetails

In the example above, the name "twin-details" references all the properties of Fred, and George gets an exact copy of the same properties. Try pasting this example into yamllint.com to see how it expands out.

One practical use I have found for these is in docker-compose files. A common docker setup for a development environment is to have a single proxy container and several application containers. In that setup, each container needs an extra_hosts section containing the host names and IP addresses for all containers in the docker compose. That repeated block is a perfect use-case for a YAML anchor.


version: '3'
services:
  proxy:
    image: nginx:1.23.1-alpine
    container_name: proxy
    hostname: dev.proxy.com
    extra_hosts: &extra_hosts
      - dev.proxy.com:10.2.0.1
      - dev.frontend.com:10.2.0.2
      - dev.microservice-1.com:10.2.0.3
      - dev.microservice-2.com:10.2.0.4
    ports:
      - "80:80"
      - "443:443"
    networks:
      proxy:
        ipv4_address: 10.2.0.1
  frontend:
    image: 'ghcr.io/company/app-frontend:23'
    container_name: frontend
    hostname: dev.frontend.com
    extra_hosts: *extra_hosts
    volumes:
      - ~/frontend/repo:/var/www/html
    ports:
      - "10080:80"
      - "10443:443"
    networks:
      proxy:
        ipv4_address: 10.2.0.2
  microservice-1:
    image: 'ghcr.io/company/microservice-1:17'
    container_name: 'microservice-1'
    hostname: dev.microservice-1.com
    extra_hosts: *extra_hosts
    volumes:
      - ~/microservice-1/repo:/var/www/html
      - ~/microservice-1/data:/var/lib/mysql
    ports:
      - "20080:80"
      - "20443:443"
      - "23306:3306"
    networks:
      proxy:
        ipv4_address: 10.2.0.3
  microservice-2:
    image: 'ghcr.io/company/microservice-2:39'
    container_name: 'microservice-2'
    hostname: dev.microservice-2.com
    extra_hosts: *extra_hosts
    volumes:
      - ~/microservice-2/repo:/var/www/html
      - ~/microservice-2/data:/var/lib/mysql
    ports:
      - "30080:80"
      - "30443:443"
      - "33306:3306"
    networks:
      proxy:
        ipv4_address: 10.2.0.4
networks:
  proxy:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 10.2.0.0/24

When adding a new microservice to the example above, the list of extra hosts only needs to be edited in a single place. Plus, the file is 12 lines of code shorter than without YAML anchors.