alltools.one
YAML
2025-06-19
7 min
alltools.one Team
YAMLAnchorsAliasesDRYConfiguration

Якоря и псевдонимы YAML: паттерны DRY-конфигурации

Повторение одной и той же конфигурации в нескольких разделах YAML-файла нарушает принцип DRY (Don't Repeat Yourself) и создаёт головную боль при поддержке. Якоря и псевдонимы YAML решают эту проблему, позволяя определить значение один раз и ссылаться на него многократно.

Базовый синтаксис

Якорь (&): помечает значение для повторного использования Псевдоним (*): ссылается на помеченное якорем значение

# Define an anchor
defaults: &default_settings
  timeout: 30
  retries: 3
  log_level: info

# Use aliases to reference it
development:
  <<: *default_settings
  log_level: debug

production:
  <<: *default_settings
  retries: 5

Ключ слияния << включает все пары ключ-значение из указанного якоря. Свойства, определённые после слияния, переопределяют значения якоря.

Результат после разрешения:

development:
  timeout: 30
  retries: 3
  log_level: debug  # overridden

production:
  timeout: 30
  retries: 5        # overridden
  log_level: info

Типы якорей

Скалярные якоря

Повторное использование одного значения:

max_connections: &max_conn 100

database:
  pool_size: *max_conn
cache:
  pool_size: *max_conn

Якоря последовательностей

Повторное использование целых списков:

common_ports: &ports
  - 80
  - 443

web_server:
  ports: *ports
load_balancer:
  ports: *ports

Якоря отображений

Повторное использование целых объектов (наиболее распространённый паттерн):

logging: &log_config
  driver: json-file
  options:
    max-size: "10m"
    max-file: "3"

services:
  api:
    logging: *log_config
  worker:
    logging: *log_config

Ключ слияния (<<)

Ключ слияния имеет определённое поведение:

  1. Он копирует все пары ключ-значение из указанного отображения
  2. Явно заданные ключи имеют приоритет над объединёнными
  3. Множественные слияния обрабатываются по порядку (при конфликтах побеждает первое)
# Multiple merges
base: &base
  a: 1
  b: 2

extra: &extra
  b: 3
  c: 4

combined:
  <<: [*base, *extra]
  # Result: a=1, b=2 (base wins), c=4

Примеры из реальной практики

Docker Compose

x-common: &common
  restart: unless-stopped
  networks:
    - app-network
  logging:
    driver: json-file
    options:
      max-size: "10m"

services:
  api:
    <<: *common
    image: myapp/api:latest
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://db:5432/myapp

  worker:
    <<: *common
    image: myapp/worker:latest
    environment:
      QUEUE_URL: redis://cache:6379

  scheduler:
    <<: *common
    image: myapp/scheduler:latest

Docker Compose использует соглашение с префиксом x- для полей расширения, содержащих якоря. Смотрите наше руководство YAML для Docker Compose для других паттернов.

GitHub Actions

jobs:
  test:
    runs-on: ubuntu-latest
    env: &common_env
      NODE_VERSION: '20'
      CI: true
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: npm test

  build:
    runs-on: ubuntu-latest
    needs: test
    env:
      <<: *common_env
      BUILD_TARGET: production
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

Kubernetes

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: app
          resources: &resources
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
        - name: sidecar
          resources: *resources  # Same resource limits

Ограничения и подводные камни

1. Нет межфайловых ссылок

Якоря работают только в пределах одного YAML-файла. Вы не можете ссылаться на якорь, определённый в другом файле. Для межфайлового переиспользования используйте инструменты шаблонизации: Helm, Jsonnet или Kustomize.

2. Нет частичного переопределения последовательностей

Вы не можете объединить и частично переопределить список — только заменить его целиком:

base_ports: &ports
  - 80
  - 443

service:
  ports: *ports  # You get exactly [80, 443]
  # Cannot add port 8080 to this list via merge

Обходное решение: определите расширенный список отдельно.

3. Порядок имеет значение

Якоря должны быть определены до того, как на них ссылаются:

# WRONG - alias before anchor
service:
  settings: *defaults

defaults: &defaults
  timeout: 30

# CORRECT - anchor before alias
defaults: &defaults
  timeout: 30

service:
  settings: *defaults

4. Не все инструменты поддерживают ключ слияния

Ключ слияния << не является частью основной спецификации YAML — это расширение для конкретного типа. Большинство популярных YAML-парсеров его поддерживают, но некоторые строгие парсеры — нет.

Проверьте использование якорей YAML с помощью нашего YAML Validator.

Часто задаваемые вопросы

Сохраняются ли якоря при конвертации YAML в JSON?

Нет. При разборе YAML якоря и псевдонимы разрешаются в их значения. В результирующем JSON значения будут развёрнуты. Это означает, что конвертация в JSON и обратно приведёт к потере DRY-структуры. Якоря существуют только в исходном формате YAML.

Можно ли использовать якоря со сложным вложенным переопределением?

Ключ слияния (<<) выполняет только поверхностное слияние — он копирует ключи верхнего уровня из помеченного якорем отображения. Вложенные объекты заменяются целиком, а не объединяются глубоко. Для глубокого слияния нужно специфическое для инструмента решение (функция merge в Helm, пользовательские YAML-процессоры).

Связанные ресурсы

Published on 2025-06-19
YAML Anchors and Aliases: DRY Configuration Patterns | alltools.one