Saltar al contenido principal

Clase 09 — Validación y Buenas Prácticas

Herramientas de validación

yamllint

# Instalar
pip install yamllint

# Validar un archivo
yamllint mi-config.yaml

# Validar con formato detallado
yamllint -f parsable mi-config.yaml

# Validar todos los archivos YAML de un directorio
yamllint .

Configurar yamllint

# .yamllint.yml
---
extends: default

rules:
line-length:
max: 120
level: warning
indentation:
spaces: 2
indent-sequences: true
comments:
min-spaces-from-content: 1
truthy:
allowed-values: ['true', 'false', 'yes', 'no']
document-start: disable
empty-lines:
max: 1
trailing-spaces: enable
new-line-at-end-of-file: enable

Validar con Python

#!/usr/bin/env python3
import yaml
import sys

try:
with open(sys.argv[1]) as f:
data = yaml.safe_load(f)
print(f"✅ YAML válido: {sys.argv[1]}")
print(f" Tipo raíz: {type(data).__name__}")
except yaml.YAMLError as e:
print(f"❌ YAML inválido: {e}")
sys.exit(1)

Validar Docker Compose

docker compose config        # Validar sintaxis
docker compose config -q # Solo validar sin mostrar salida
docker compose config --format json # Configuración resuelta

Validar manifiestos de Kubernetes

kubectl apply -f deployment.yaml --dry-run=client   # Dry-run cliente
kubectl apply -f deployment.yaml --dry-run=server # Dry-run servidor (más estricto)
kubeval deployment.yaml # Usando kubeval
kubeconform -strict deployment.yaml # Usando kubeconform (más moderno)

Errores comunes y cómo evitarlos

1. Tabs vs Espacios

# ❌ ERROR: Tab character
servicio:
nombre: api # Tab!

# ✅ CORRECTO: Espacios
servicio:
nombre: api # 2 espacios

2. Tipo de dato incorrecto

# ❌ PROBLEMA
version: 3.8 # → 3.8 (float)
puerto: 080 # → 80 (octal → decimal)
codigo: no # → false (boolean)

# ✅ SOLUCIÓN: Usar comillas
version: "3.8" # → "3.8" (string)
puerto: "080" # → "080" (string)
codigo: "no" # → "no" (string)

3. Caracteres especiales sin escapar

# ❌ PROBLEMA
titulo: Hola: Mundo # Error: : sin comillas
comando: echo "hola" # Las comillas internas

# ✅ SOLUCIÓN
titulo: "Hola: Mundo"
comando: 'echo "hola"'

4. Indentación inconsistente

# ❌ PROBLEMA: Mezclar 2 y 4 espacios
servicio:
nombre: api
config:
puerto: 8080 # 4 espacios en vez de 2

# ✅ CORRECTO: Consistente (2 espacios)
servicio:
nombre: api
config:
puerto: 8080

5. Duplicar claves

# ❌ PROBLEMA: Clave duplicada (la segunda sobrescribe)
servicio:
nombre: api
puerto: 8080
nombre: backend # Sobrescribe "api"

# ✅ CORRECTO: Claves únicas
servicio:
nombre: api
nombre_display: backend
puerto: 8080

Buenas prácticas

1. Indentación consistente de 2 espacios

services:
api:
image: mi-api:latest
ports:
- "8080:8080"

2. Siempre usar comillas en valores ambiguos

version: "3.8"
environment:
NODE_ENV: "production"
PORT: "8080"
DEBUG: "false"

3. Comentar secciones importantes

# ─── BASE DE DATOS ───
database:
host: postgres # Nombre del servicio en Docker/K8s
port: 5432
pool_size: 10 # Ajustar según carga esperada

# ─── CACHÉ ───
cache:
engine: redis
ttl: 3600 # 1 hora en segundos

4. Usar anclas para DRY

x-common: &common
restart: unless-stopped
logging:
driver: json-file

services:
api:
<<: *common
image: api:latest
worker:
<<: *common
image: worker:latest

5. Organizar archivos por responsabilidad

k8s/
├── base/
│ ├── namespace.yaml
│ ├── configmap.yaml
│ └── secret.yaml
├── deployments/
│ ├── api.yaml
│ └── frontend.yaml
├── services/
│ ├── api-svc.yaml
│ └── frontend-svc.yaml
└── ingress/
└── main-ingress.yaml

6. Usar variables de entorno para secretos

# docker-compose.yml - Nunca hardcodear secretos
services:
db:
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD} # Desde .env o sistema

7. Validar en CI/CD

# .github/workflows/lint.yml
name: YAML Lint

on: [push, pull_request]

jobs:
yamllint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Instalar yamllint
run: pip install yamllint
- name: Lint YAML
run: yamllint .
- name: Validar Docker Compose
run: docker compose config -q
- name: Validar K8s manifests
run: |
curl -sL https://github.com/yannh/kubeconform/releases/latest/download/kubeconform-linux-amd64.tar.gz | tar xz
./kubeconform -strict k8s/

Cheat Sheet

# ── TIPOS DE DATOS ──
string: "texto"
entero: 42
flotante: 3.14
booleano: true
nulo: null
fecha: 2026-02-20

# ── LISTAS ──
lista_bloque:
- item1
- item2
lista_inline: [item1, item2]

# ── MAPAS ──
mapa_bloque:
clave1: valor1
clave2: valor2
mapa_inline: {clave1: valor1, clave2: valor2}

# ── MULTILÍNEA ──
literal: | # Mantiene \n
línea 1
línea 2
folded: > # Une en una línea
parte 1
parte 2
sin_newline: |- # Sin \n final
texto

# ── ANCLAS ──
base: &base
key: value
hijo:
<<: *base
otra_key: otro_valor

# ── MULTI-DOCUMENTO ──
---
documento: 1
---
documento: 2

Ejercicios

  1. Configurá yamllint en tu proyecto y corregí todos los errores
  2. Creá un workflow de GitHub Actions que valide todos los archivos YAML del repositorio
  3. Revisá un docker-compose.yml existente y aplicá todas las buenas prácticas de esta clase
  4. Creá una guía de estilo YAML para tu equipo basada en lo aprendido