Si alguna vez has copiado un bloque de YAML de un lugar a otro en un archivo, ya experimentaste el problema que las anclas y los alias resuelven. Las grandes configuraciones de Kubernetes, los archivos Docker Compose multi-entorno y los pipelines CI complejos tienden a repetir los mismos bloques — límites de recursos, variables de entorno, montajes de volúmenes — una y otra vez. YAML tiene una respuesta integrada para esto, y la mayoría de los desarrolladores no saben que existe.

Las anclas (&) y los alias (*) son el mecanismo de YAML para definir un valor una vez y referenciarlo en cualquier otro lugar del mismo archivo. Piensa en un ancla como declarar una variable y en un alias como usarla. La clave de fusión (<<) extiende esto a la fusión de objetos — similar al operador de propagación de JavaScript. Ambas características están definidas en la sección de anclas de nodo de la especificación YAML 1.2.

Sintaxis básica de anclas y alias

La sintaxis es mínima. Prefija un valor con &nombre para crear un ancla, luego usa *nombre en cualquier parte del documento para referenciarlo:

yaml
# Define the anchor once
default_timeout: &timeout 30

# Reference it multiple times
services:
  api:
    timeout: *timeout      # → 30
  worker:
    timeout: *timeout      # → 30
  scheduler:
    timeout: *timeout      # → 30

Cuando un parser YAML lee esto, cada alias se resuelve al mismo valor exacto que el ancla. Cambia el ancla y todos los alias se actualizan. No se necesita buscar y reemplazar.

Fusión de objetos con la clave <<

La reutilización de escalares es útil, pero el verdadero poder viene de fusionar bloques de mapping enteros. La clave de fusión << absorbe todos los pares clave-valor del ancla referenciada en el mapping actual:

yaml
# Define a base configuration block
base_service: &base
  restart: unless-stopped
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "3"
  networks:
    - app-network

# Merge it into specific services
services:
  api:
    <<: *base              # merge all keys from base_service
    image: my-api:latest
    ports:
      - "8080:8080"

  worker:
    <<: *base              # same base config
    image: my-worker:latest
    command: ["node", "worker.js"]

  scheduler:
    <<: *base              # and again
    image: my-scheduler:latest
    command: ["node", "cron.js"]

Las claves definidas directamente en el mapping sobreescriben las claves del ancla fusionada. Entonces si base establece restart: unless-stopped y el servicio también establece restart: no, gana el valor a nivel de servicio.

Antes y después: Docker Compose en el mundo real

Así es como se ve un archivo Docker Compose típico multi-servicio sin anclas — lleno de repetición:

yaml
# BEFORE — repetitive and hard to maintain
version: "3.9"
services:
  api:
    restart: unless-stopped
    env_file: .env
    networks: [app-network]
    logging:
      driver: json-file
      options:
        max-size: "10m"
    depends_on:
      - postgres

  worker:
    restart: unless-stopped
    env_file: .env
    networks: [app-network]
    logging:
      driver: json-file
      options:
        max-size: "10m"
    depends_on:
      - postgres

  mailer:
    restart: unless-stopped
    env_file: .env
    networks: [app-network]
    logging:
      driver: json-file
      options:
        max-size: "10m"
    depends_on:
      - postgres

Ahora con anclas y la clave de fusión — cada bloque repetido se define exactamente una vez:

yaml
# AFTER — DRY and easy to maintain
version: "3.9"

x-common: &common
  restart: unless-stopped
  env_file: .env
  networks: [app-network]
  logging:
    driver: json-file
    options:
      max-size: "10m"
  depends_on:
    - postgres

services:
  api:
    <<: *common
    image: my-api:2.4.1
    ports:
      - "8080:8080"

  worker:
    <<: *common
    image: my-worker:2.4.1
    command: ["node", "worker.js"]

  mailer:
    <<: *common
    image: my-mailer:2.4.1
    command: ["node", "mailer.js"]
Consejo profesional: El prefijo x- en los campos de extensión (como x-common) es una convención de Docker Compose que evita que Compose intente analizar el bloque como una definición de servicio. El motor de Compose lo ignora pero es completamente utilizable como ancla YAML.

GitHub Actions: estrategia matrix con anclas

La configuración de CI es otro lugar donde las anclas rinden frutos. Aquí hay un flujo de trabajo de GitHub Actions que reutiliza la configuración común de pasos en múltiples jobs:

yaml
name: Build and Test

on: [push, pull_request]

# Shared setup steps
x-setup-steps: &setup-steps
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: "20"
      cache: npm
  - run: npm ci

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - *setup-steps
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
      - *setup-steps
      - run: npm test -- --coverage

  build:
    runs-on: ubuntu-latest
    steps:
      - *setup-steps
      - run: npm run build

Nota: el parser YAML de GitHub Actions sí soporta anclas y alias. Sin embargo, algunos sistemas CI (especialmente CircleCI antes de la versión 2.1) tenían su propia sintaxis de extensión similar a las anclas. Siempre verifica la documentación de tu herramienta específica.

Kubernetes: reutilizar límites de recursos

En los manifiestos de Kubernetes, los límites de recursos y las variables de entorno son candidatos ideales para anclas. Aquí hay un patrón que uso regularmente:

yaml
# Anchors at the top of the file (or in a shared ConfigMap generator)
x-resources:
  small: &resources-small
    requests:
      memory: "64Mi"
      cpu: "50m"
    limits:
      memory: "256Mi"
      cpu: "200m"
  large: &resources-large
    requests:
      memory: "256Mi"
      cpu: "200m"
    limits:
      memory: "1Gi"
      cpu: "1000m"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  template:
    spec:
      containers:
        - name: frontend
          image: frontend:latest
          resources: *resources-small    # reuse small profile

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  template:
    spec:
      containers:
        - name: api
          image: api:latest
          resources: *resources-large    # reuse large profile

Fusiones múltiples y prioridad de sobreescritura

Puedes fusionar desde múltiples anclas en un solo mapping. Proporciónales como una lista bajo <<. Las entradas anteriores en la lista tienen prioridad sobre las posteriores para claves duplicadas:

yaml
defaults: &defaults
  color: blue
  size: medium
  weight: light

overrides: &overrides
  color: red          # will override defaults.color
  weight: heavy       # will override defaults.weight

result:
  <<: [*overrides, *defaults]    # overrides takes priority
  name: widget
# Result: color=red, size=medium, weight=heavy, name=widget

Limitaciones a conocer

  • Solo el mismo archivo. Las anclas y los alias solo funcionan dentro de un único flujo de documento YAML. No puedes referenciar un ancla desde un archivo diferente. Para reutilización entre archivos, necesitas el mecanismo propio de tu herramienta (por ejemplo, templates de Helm, Kustomize, o procesadores YAML como ytt).
  • Sin valores calculados. Los alias se resuelven como copias exactas del valor del ancla. No hay interpolación ni lógica de plantilla — eso es para herramientas como Helm o Jinja2.
  • La clave de fusión es una extensión YAML. La clave de fusión << está definida en una extensión YAML 1.1, no en la especificación principal. La mayoría de los parsers la soportan, pero los parsers YAML 1.2 estrictamente conformes a la especificación pueden no hacerlo.
  • Las referencias circulares rompen los parsers. No intentes anclar un nodo y luego referenciarlo desde dentro de sí mismo. Es técnicamente inválido.
  • Los alias copian, no referencian. Modificar el valor de un alias resuelto en tu código no cambia el ancla ni los otros alias. Son valores independientes después del análisis.

Conclusión

Las anclas y los alias de YAML son una de las características más infrautilizadas del formato. En cualquier archivo YAML de más de unas 50 líneas donde el mismo bloque de configuración aparece más de dos veces, las anclas casi con certeza tienen su lugar allí. La diferencia antes/después en mantenibilidad es dramática — cambiar un perfil de límite de recursos o una variable de entorno compartida en lugar de buscar por todo el archivo. Usa el Formateador YAML para mantener ordenados tus archivos con anclas, y el Validador YAML para confirmar que tus referencias de ancla se resuelven correctamente.