DevOps

Automatización en Linux: Splunk y Ansible para Incidentes

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 minutos a 2 horas dependiendo de la complejidad del entorno.
  • Requisitos: Acceso root, Linux moderno, conexión a internet para descargar dependencias.
  • Resultado: Servicio funcional y estable, documentado paso a paso.
  • Troubleshooting: Logs estándar en /var/log/, comandos de verificación al final de cada sección.

Por qué los SRE están cansados de apagar incendios a las 3 AM

Si alguna vez te tocó un on-call respondiendo la misma alerta cuatro veces por noche — reiniciar un servicio, rotar un certificado, escalar un contenedor que se quedó sin memoria — el problema es claro: detectar es la mitad del trabajo. La otra mitad, la remediación, es la que se come el MTTR (Mean Time To Resolution).

El 11 de septiembre de 2026, Red Hat publicó una integración de referencia entre Splunk Observability Cloud y Red Hat Ansible Automation Platform (AAP) que cierra ese loop. La idea no es nueva — Splunk detecta, un webhook llega a AAP, un rulebook ejecuta el playbook correcto — pero la combinación con Event-Driven Ansible y el add-on certificado por Splunkbase hace que el patrón sea repetible fuera de los Fortune 500. Lo que sigue es la versión propia de ese flujo, pensada para sysadmins y devops juniors que corren entre 1 y 20 servidores Linux, no 5.000.

El artículo original describe un escenario enterprise con clusters Kubernetes, RBAC granular y un equipo de SRE dedicado. El patrón sirve igual para un homelab con 3 servidores, siempre que se entienda dónde está la línea entre “vale la pena automatizar” y “esto se está complicando”.

El loop AIOps en una sola imagen mental

Cuatro componentes, en orden:

  1. Splunk OpenTelemetry Collector: un agente único que recoge métricas, trazas y logs de hosts, contenedores y pods Kubernetes. Envía la telemetría al observability cloud.
  2. Splunk Observability Cloud: agrega la telemetría y aplica detectores con IA para encontrar degradación antes que los usuarios.
  3. Webhook (o el Splunk add-on for Event-Driven Ansible): manda el payload estructurado al Ansible Automation Platform.
  4. Ansible Automation Platform con Event-Driven Ansible: matchea el evento contra un rulebook aprobado y dispara el playbook de remediación con RBAC, credenciales vaultadas y auditoría completa.

La diferencia con un script bash colgado en cron está en tres letras: HITL (human-in-the-loop). El rulebook puede pedir aprobación explícita antes de tocar producción, o ejecutar el fix si la política lo permite. Si la remediación falla, escala a on-call por ITSM (ServiceNow, Jira, etc.) con todo el contexto adjunto.

El detalle que casi nadie menciona: el HITL no es solo “una pausa”. Es el mecanismo que separa el auto-healing del auto-incendio. Una alerta mal calibrada más un playbook sin idempotencia más HITL apagado tira producción abajo en la primera hora de operación. Volvemos a esto más adelante.

Por qué importa aunque el entorno sea chico

El artículo de Red Hat está escrito para enterprise, pero el patrón escala hacia abajo. Los casos reales más comunes en homelab o pyme:

  • Una app Node se queda sin memoria cada 3-4 días por un leak conocido. La solución manual es reiniciar el proceso y cruzar los dedos.
  • Los certificados Let’s Encrypt vencen en 60 días y un script nocturno los renueva, pero nadie verifica que la app de verdad haya recargado TLS.
  • Un cron genera un log gigante que llena /var/log. El problema se descubre cuando SSH tarda 30 segundos en responder.
  • Una app en Python levanta un thread zombie cada vez que recibe un webhook malformado. Reiniciar el proceso manualmente es la rutina de lunes a viernes.

En cada caso, detectar es trivial (Prometheus + Grafana o cualquier monitor). Lo que falta es la remediación automática, con guardarraíles, sin tener que escribir un wrapper bash por incidente.

La métrica correcta es MTTR end-to-end: desde el momento en que el detector ve el problema hasta que el servicio vuelve a estar sano. La mayoría de las operaciones miden solo time-to-alert, que es la parte fácil.

Cómo se ve el flujo con un leak de memoria

Ejemplo concreto del paso a paso (memoria > 90% en app servers):

  1. Deploy & detect: AAP despliega el Splunk OTel Collector vía la collection cisco.splunk_otel_collector. Memoria cruza 90%. Splunk ve GC pause times subiendo y latencia creciendo, dispara alerta.
  2. Event forwarding: el webhook manda el payload (hostnames, valores, severidad) a AAP como evento estructurado.
  3. Event received: Event-Driven Ansible levanta el evento desde el bus.
  4. Rule matching: AAP evalúa contra los rulebooks pre-aprobados por el equipo de operaciones.
  5. ITSM sync (opcional): crea o actualiza un ticket en ServiceNow o Jira antes de tocar nada, para mantener trazabilidad.
  6. Rule evaluation: el rulebook pasa el contexto (hostnames, thresholds) al playbook de remediación como variables.
  7. Execute with approval: el playbook corre con HITL, o automático si la política lo define para esa clase de alerta.
  8. Remediate: reinicia el proceso con rolling strategy, 1 host a la vez, validando health checks entre cada restart. Si vuelve a fallar, otro rule escala a on-call por ITSM con todos los intentos automáticos documentados.

El truco está en el paso 7: rolling + health check. No es un systemctl restart a ciegas. Es Ansible reiniciando de a uno, esperando que el endpoint de salud responda 200, y recién pasando al siguiente. La diferencia entre los dos enfoques se nota la primera vez que se obtiene un reinicio “exitoso” pero el servicio quedó zombie.

¿Y si todavía no existe el playbook?

Para la mayoría de las alertas comunes ya hay collections certificadas en Ansible automation hub: reinicio de servicio, rotación de logs, escalado de deployment, limpieza de caché, rotación de credenciales. Para el resto, AAP 2.5+ trae un automation coding assistant y un MCP server oficial con el que se puede generar el playbook desde un prompt en lenguaje natural.

No es magia: necesita revisión humana antes de producción. Pero baja el “tiempo al primer fix” de horas a minutos. El flujo real es: describir en una línea qué tiene que pasar, el assistant genera un playbook base con módulos estándar (ansible.builtin.service, ansible.builtin.shell con guardas), revisar y commitear al repo, y queda disponible para el rulebook. La parte de review es lo que evita terminar con rm -rf / en un playbook generado por LLM.

Trade-offs que el artículo de Red Hat no discute

Aspecto Lo que prometen La realidad en el server propio
Costo de AAP Incluido en suscripción enterprise Self-hosted AAP (operator Kubernetes) existe pero requiere cluster
Complejidad inicial “Desplegar collectors con un run” El primer despliegue lleva 1-2 días; el segundo, 30 minutos
Latencia del loop “Segundos en vez de horas” Verdadero, pero solo si el detector está bien calibrado
Falsos positivos Mencionalos, sin métrica Sin HITL estricto se termina tirando producción abajo una vez por mes
Vendor lock-in “Open source en el core” AAP es open source, Splunk Observability Cloud no
Curva de aprendizaje “Reglas en YAML declarativo” Las reglas en YAML son fáciles; entender Event-Driven Ansible lleva semanas

Para un homelab serio, AAP es overkill. Para una pyme con 10-50 servers y un SRE a tiempo completo, el ROI aparece en el segundo trimestre. Para una startup con 3 servers y un solo devops part-time, AAP distrae de lo que importa: alertas decentes y un runbook que documente qué hacer a mano.

Cómo empezar sin comprar nada (versión sysadmin)

Si todavía no se cuenta con AAP ni Splunk Observability Cloud, se puede capturar el 80% del valor con herramientas que ya están en el server. El patrón se reduce a tres piezas: detector, receptor y playbook. Prometheus + alertmanager como detector, un script bash como receptor, y ansible-playbook como ejecutor.

El detector Prometheus

La primera pieza es el detector. Se define una regla que publique un webhook cuando la memoria libre cae bajo umbral:

# /etc/prometheus/rules/memoria.yaml
groups:
- name: memoria
  rules:
  - alert: MemoryPressureHigh
    expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) < 0.10
    for: 5m
    labels:
      severity: warning
      playbook: restart_app.yml
    annotations:
      summary: "Memoria disponible < 10% en {{ $labels.instance }}"

La label playbook es custom y la lee el receptor para decidir qué playbook correr. La cláusula for: 5m es la ventana de absorción: sin ella, un pico de 2 segundos dispara remediación.

El receptor en bash

La segunda pieza es un script que alertmanager invoca por webhook. Recibe el payload, identifica el playbook por la label, y delega a ansible-playbook:

#!/bin/bash
# /usr/local/bin/auto_remediation.sh
# Receptor del webhook de alertmanager
set -euo pipefail
ALERT_PAYLOAD=$(cat)
ALERTNAME=$(echo "$ALERT_PAYLOAD" | jq -r '.alerts[0].labels.alertname // empty')
INSTANCE=$(echo "$ALERT_PAYLOAD" | jq -r '.alerts[0].labels.instance // empty')
PLAYBOOK=$(echo "$ALERT_PAYLOAD" | jq -r '.alerts[0].labels.playbook // empty')
SUMMARY=$(echo "$ALERT_PAYLOAD" | jq -r '.alerts[0].annotations.summary // empty')
logger -t auto-remediation "ALERTA: $ALERTNAME en $INSTANCE, ejecutando $PLAYBOOK"

La guarda set -euo pipefail evita que el script continúe cuando una variable viene vacía. Sin eso, una alerta malformada ejecuta comandos con strings vacíos.

El dispatch según label

El receptor dispatcha al playbook correcto según la label playbook. Si no hay match, escala a on-call:

case "$PLAYBOOK" in
  restart_app.yml)
    ansible-playbook -i /etc/ansible/hosts /etc/ansible/playbooks/restart_app.yml 
      -e "target_host=$INSTANCE"
    ;;
  rotate_logs.yml)
    ansible-playbook -i /etc/ansible/hosts /etc/ansible/playbooks/rotate_logs.yml 
      -e "target_host=$INSTANCE"
    ;;
  renew_certs.yml)
    ansible-playbook -i /etc/ansible/hosts /etc/ansible/playbooks/renew_certs.yml 
      -e "target_host=$INSTANCE"
    ;;
  *)
    logger -t auto-remediation "Sin playbook para $PLAYBOOK, escalando a on-call"
    /usr/local/bin/notify_oncall.sh "$ALERTNAME" "$INSTANCE" "$SUMMARY"
    exit 1
    ;;
esac

El wildcard *) es la red de seguridad: cualquier alerta sin playbook definido escala al on-call en vez de fallar silenciosamente.

La verificación post-fix

La pieza que casi nadie incluye: después del fix, verificar que el servicio volvió sano. Sin esto, un auto-remediation es un incendio silencioso:

sleep 30
if /usr/local/bin/check_health.sh "$INSTANCE"; then
    logger -t auto-remediation "Recuperado: $INSTANCE"
    /usr/local/bin/notify_oncall.sh "$ALERTNAME" "$INSTANCE" "Auto-fix OK"
else
    /usr/local/bin/notify_oncall.sh "$ALERTNAME" "$INSTANCE" 
      "Auto-fix falló, revisión manual requerida"
    exit 1
fi

El sleep 30 le da tiempo al servicio a levantar. check_health.sh es un script que hace curl -fs http://$INSTANCE:8080/health o el equivalente para tu app. Si falla, se notifica a on-call con el contexto completo.

El playbook mínimo

El playbook llamado por el receptor es estándar Ansible. La clave es la idempotencia y el rolling restart:

# /etc/ansible/playbooks/restart_app.yml
- name: Reinicio rolling de app con leak de memoria
  hosts: "{{ target_host }}"
  serial: 1
  become: true
  tasks:
    - name: Health check pre-restart
      ansible.builtin.uri:
        url: "http://{{ ansible_host }}:8080/health"
        status_code: 200
      register: pre
      failed_when: false
    - name: Reiniciar servicio
      ansible.builtin.systemd:
        name: miapp
        state: restarted
      when: pre.status == 200
    - name: Esperar a que vuelva el health
      ansible.builtin.wait_for:
        host: "{{ ansible_host }}"
        port: 8080
        timeout: 60

serial: 1 ejecuta el playbook en un host a la vez. Si la flota tiene 5 app servers, los reinicia uno por uno, validando que cada uno vuelva sano antes de pasar al siguiente. Sin serial: 1, todos se reinician en paralelo y la app queda caída durante la ventana de reinicio.

El health check externo

El script check_health.sh que valida el post-fix es simple, pero clave. Acá la versión robusta:

#!/bin/bash
# /usr/local/bin/check_health.sh
# Devuelve 0 si el servicio responde 200 en /health
set -e
HOST="${1:?Falta host}"
TIMEOUT="${HEALTH_TIMEOUT:-10}"
HEALTH_URL="${HEALTH_URL:-http://${HOST}:8080/health}"
for i in 1 2 3; do
    if curl -fsS --max-time "$TIMEOUT" "$HEALTH_URL" >/dev/null; then
        echo "OK: $HEALTH_URL responde 200"
        exit 0
    fi
    sleep 5
done
echo "FAIL: $HEALTH_URL no responde después de 3 intentos"
exit 1

El loop de 3 intentos con sleep 5 entre cada uno le da al servicio tiempo suficiente para levantar el puerto TCP y bindear la app. Sin retries, un reinicio lento marca falso negativo.

Lo que falta y lo que se gana

Esto da la columna vertebral del patrón AIOps sin AAP ni Splunk. Lo que falta es el RBAC, el audit trail centralizado, el dashboard de eventos, y el versioning de rulebooks. Si la operación crece, AAP resuelve todo eso. Si no, este script más un buen runbook cubre 1-10 servers sin dramas.

Errores comunes que cuestan la noche

Tres patrones rompen el loop silenciosamente:

  1. Detector sin ventana de evaluación: for: 0s en la alerta significa que un pico de 2 segundos dispara remediación. El mínimo sano es for: 5m para alertas de memoria, for: 2m para disco lleno, for: 10m para latencia alta. La ventana absorbe picos normales de tráfico.
  2. Playbook sin idempotencia: si el webhook se duplica, un reinicio sin idempotencia deja el servicio caído. ansible-playbook es idempotente por diseño, pero los módulos custom pueden no serlo. Regla: cada tarea debería poder correr dos veces seguidas sin cambiar el estado final.
  3. HITL siempre en off: en producción, la aprobación humana es lo que separa “auto-healing” de “auto-incendio”. Empezar con HITL obligatorio y solo apagarlo cuando se tengan 3 meses de datos sin falsos positivos. La presión del equipo por apagar HITL va a ser fuerte; resistila.

Cuándo NO hacerlo

El loop AIOps no es para todo. No conviene para:

  • Servicios con estado donde un reinicio pierde datos (bases de datos relacionales sin replica, colas sin persistencia).
  • Alertas de seguridad. La remediación automática de un hallazgo escala rápido a desastre. HITL obligatorio siempre, y cuidado con runbooks de containment que bloquean usuarios legítimos.
  • Cambios que afectan compliance (rotación de claves, cambios de firewall, modificaciones de auditoría). Aunque sean repetitivos, la auditoría humana va por encima del automation.
  • Alertas de baja frecuencia sin playbooks probados. Si la alerta salta una vez al año, no automatizar; dejar al on-call con un runbook documentado.

La regla mental: si la remediación tiene efecto irreversible en datos o compliance, HITL obligatorio o no automatizar.

Resumen

El loop AIOps de Red Hat + Splunk es la versión enterprise de un patrón que ya se puede implementar gratis con Prometheus + alertmanager + un script bash. Lo que AAP compra es gobernanza (RBAC, auditoría, scheduling, vault) y la UI para que un equipo no-devops opere rulebooks sin tocar YAML. Con menos de 10 servers, conviene empezar por el script y un runbook claro. Con más, AAP vale cada centavo, pero solo después de tener el patrón funcionando en casa.

El error más común es tratar detección y remediación como problemas separados. La métrica que importa es MTTR end-to-end, no el time-to-alert ni el time-to-fix aisladamente. Si el time-to-alert es 30 segundos pero el time-to-fix es 2 horas porque nadie sabe qué playbook correr, el loop de firefighting manual sigue intacto.

Lo que se deja para el final: documentar cada rulebook con el link al incidente que lo motivó. Cuando el playbook se rompe 6 meses después y nadie se acuerda por qué existía, el incidente original en el runbook ahorra una hora de arqueología.

Preguntas frecuentes

¿Por qué Automatización en Linux: Splunk y Ansible para Incidentes es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Automatización en Linux: Splunk y?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Automatización en Linux: Splunk y?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Automatización en Linux: Splunk y y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Automatización en Linux: Splunk y?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *