¿Qué es YAML?
YAML — originalmente "Yet Another Markup Language", luego rebautizado como YAML Ain't Markup Language — es un formato de serialización de datos legible por humanos diseñado para ser fácil de mapear a estructuras de datos en lenguajes de programación. Definido por Clark Evans, Ingy döt Net y Oren Ben-Kiki en 2001, alcanzó la versión 1.2.2 en 2021.
YAML es el formato de configuración dominante para las herramientas DevOps modernas: Docker Compose, manifiestos de Kubernetes, GitHub Actions, playbooks de Ansible, GitLab CI, charts de Helm y muchos otros sistemas lo usan como interfaz humana.
Modelo de Datos Central
YAML se mapea a tres tipos de datos fundamentales:
| Término YAML | Equivalente |
|---|---|
| Escalar | Cadena, entero, flotante, booleano, nulo, fecha |
| Secuencia | Lista ordenada (array) |
| Mapeo | Pares clave-valor (hash/dict/objeto) |
Sintaxis Básica
# Comentario YAML
# Escalares
nombre: KaijuConverter
version: 2.1.0
activo: true
precio: 9.99
descripcion: null # o ~
# Secuencia de bloque (lista)
etiquetas:
- convertidor
- herramientas
- web
# Secuencia de flujo (inline)
colores: [rojo, verde, azul]
# Mapeo de bloque (objeto anidado)
base_de_datos:
host: localhost
puerto: 5432
nombre: kaijudb
opciones:
ssl: true
timeout: 30
# Mapeo de flujo (inline)
punto: {x: 10, y: 20}
Cadenas Multilínea
YAML tiene dos estilos de escalares de bloque para texto multilínea:
Escalar literal (|) — preserva los saltos de línea:
mensaje: |
Estimado usuario,
Bienvenido a KaijuConverter.
¡Disfruta convirtiendo archivos!
Escalar plegado (>) — convierte saltos de línea en espacios (como un párrafo):
descripcion: >
Esta es una descripción larga que
se plegará en una sola línea
al ser analizada.
Ambos soportan indicadores de recorte:
|-/>-— eliminar salto de línea final (strip)|+/>+— mantener todos los saltos de línea finales (keep)|/>— mantener exactamente un salto de línea final (clip, por defecto)
Anclas y Alias
YAML permite reutilizar contenido de nodos sin duplicación:
defaults: &defaults
imagen: ubuntu:22.04
restart: always
entorno:
- NODE_ENV=production
web:
<<: *defaults
puertos:
- "80:3000"
api:
<<: *defaults
puertos:
- "8080:8080"
&ancladefine un ancla nombradadefaults.*aliasla referencia (se duplica el mapeo completo).<<:es la clave de fusión — fusiona el mapeo referenciado en el actual, permitiendo sobrescribir.
Marcadores de Documentos
Un archivo YAML puede contener múltiples documentos separados por ---:
---
nombre: documento uno
---
nombre: documento dos
...
Kubernetes lo usa para agrupar varios recursos en un archivo. Ansible lo usa para playbooks multitarea.
Coerción de Tipos — El Problema Notorio
YAML 1.1 aplica coerción de tipos implícita agresiva:
| Valor | Tipo YAML 1.1 | Tipo YAML 1.2 |
|---|---|---|
true, yes, on |
booleano true |
solo true es booleano |
false, no, off |
booleano false |
solo false es booleano |
null, ~ |
nulo | nulo |
0755 |
octal 493 |
cadena "0755" |
2001-01-23 |
fecha | cadena |
NO |
booleano false |
cadena "NO" |
El Problema de Noruega: el código de país NO se analiza como booleano false en YAML 1.1. Siempre entrecomilla valores ambiguos:
pais: "NO" # cadena "NO"
activado: true # booleano true
modo_octal: "0755" # cadena "0755", no octal 493
YAML vs. JSON
YAML es un superconjunto de JSON a partir de YAML 1.2. Diferencias clave:
| Característica | YAML | JSON |
|---|---|---|
| Comentarios | Sí (#) |
No |
| Cadenas multilínea | Sí (literal/plegado) | No (escapa \n) |
| Cadenas sin comillas | Sí | No |
| Anclas/alias | Sí | No |
| Múltiples documentos | Sí | No |
| Verbosidad | Baja | Media |
| Complejidad de análisis | Muy alta | Baja |
| Riesgo de seguridad | Mayor | Menor |
Seguridad: Ataques de Deserialización YAML
YAML admite etiquetas que instruyen al analizador para construir objetos específicos:
!!python/object/apply:os.system ['rm -rf /']
Un analizador que permita la construcción de etiquetas arbitrarias ejecutará esto. Usa siempre cargadores seguros:
# INSEGURO — nunca hacer esto con entrada no confiable
datos = yaml.load(cadena_no_confiable)
# SEGURO
datos = yaml.safe_load(cadena_no_confiable) # Python
datos = YAML::safe_load(cadena_no_confiable) # Ruby
YAML en Ecosistemas CI/CD
GitHub Actions:
name: CI
on: [push, pull_request]
jobs:
prueba:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ejecutar pruebas
run: npm test
Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: kaiju-web
spec:
replicas: 3
selector:
matchLabels:
app: kaiju
Docker Compose:
version: "3.9"
services:
app:
build: .
ports:
- "8080:80"
depends_on:
- bd
bd:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secreto
Validación y Herramientas
- yamllint: linter Python que verifica sintaxis, estilo (sangría, longitud de línea, valores verdaderos).
- kubeconform: valida YAML de Kubernetes contra esquemas API oficiales.
- VS Code extensión YAML (Red Hat): IntelliSense, asociación de esquemas, errores en línea.
- yq: herramienta de línea de comandos para procesar y convertir YAML.
Conversión de YAML
- YAML → JSON:
yq e -o=json entrada.yaml, o Pythonjson.dumps(yaml.safe_load(f)). - YAML → TOML:
yq e -o=toml entrada.yaml(yq 4.x). - JSON → YAML:
yq e -P entrada.json(convertir y embellecer).
Buenas Prácticas
- Usa siempre
safe_loadal analizar entrada no confiable. - Entrecomilla cadenas que podrían interpretarse como booleanos, números o fechas.
- Usa sangría de 2 espacios — los tabuladores están prohibidos en YAML.
- Valida con yamllint en CI antes de desplegar cambios de configuración.
- Usa anclas para bloques repetidos en lugar de copiar y pegar.
- Añade
---al inicio de cada archivo para señalar que es un documento YAML. - Evita el anidamiento profundo — más de 4 niveles se vuelve difícil de mantener.
- Usa analizadores compatibles con YAML 1.2 para evitar el Problema de Noruega.
Conversiones relacionadas
Conversiones frecuentes del catálogo: