Ansible para sysadmins: casos prácticos que no están en el tutorial
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é este artículo y no el típico “Ansible desde cero”
Si buscas una introducción básica a Ansible, ya hay material en soylinux.com. Este artículo va un paso más allá: los casos prácticos reales que un sysadmin Linux termina usando una vez que ya pasó la fase “hello world” de los playbooks. Hablamos de idempotencia dura, Ansible Vault, módulos útiles que mucha gente pasa por alto, dynamic inventory, y patrones que evitan que tu playbook se rompa en producción a las 3 AM.
Ansible Vault: secretos sin filtrarlos en el repo
El error más común es dejar contraseñas en group_vars/all.yml en texto plano y commitear el repo. ansible-vault resuelve esto cifrando el archivo con AES256. El playbook queda ejecutable, pero el contenido es ilegible sin la clave maestra.
Crear un archivo cifrado:
ansible-vault create group_vars/production/vault.yml
# Te pide una contraseña maestra. Guárdala en tu gestor de claves
# (pass, Bitwarden, 1Password), NO en el repo.
Para editarlo después:
ansible-vault edit group_vars/production/vault.yml
ansible-vault view group_vars/production/vault.yml
ansible-vault rekey group_vars/production/vault.yml # cambiar contraseña
Para usar las variables en el playbook, ejecutas con --ask-vault-pass o con un archivo de contraseña:
ansible-playbook site.yml --ask-vault-pass
# O mejor, archivo con permisos restrictivos:
echo 'mi_clave_maestra' > ~/.vault_pass && chmod 600 ~/.vault_pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Dentro del playbook referencias las variables con el prefijo vault_ para que quede claro que vienen del vault cifrado:
- hosts: webservers
vars_files:
- group_vars/production/vault.yml
tasks:
- name: Configurar base de datos
mysql_user:
name: "{{ vault_db_user }}"
password: "{{ vault_db_password }}"
priv: '*.*:ALL'
state: present
Troubleshooting: si al ejecutar el playbook te aparece ERROR! Decryption failed, casi siempre es porque editaste el archivo con un editor que no respeta los finales de línea Unix. Usa siempre ansible-vault edit, no vi vault.yml directamente sobre el archivo cifrado.
Idempotencia: por qué command: es un antipatrón
El mantra de Ansible es “declarar el estado final, no los pasos para llegar”. Cuando escribes una task con command:, Ansible ejecuta ese comando siempre, sin importar si el estado deseado ya existe. Eso rompe la idempotencia y termina con efectos secundarios difíciles de debuggear.
Ejemplo MALO:
- name: Instalar nginx
command: apt-get install -y nginx # Se ejecuta cada vez, aunque ya esté instalado
Ejemplo BUENO:
- name: Instalar nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: yes
El módulo apt primero chequea si el paquete está instalado, y solo ejecuta apt-get install si hace falta. Corre el playbook 10 veces seguidas: la primera tarda 30 segundos, las siguientes 2 segundos. Con command: tardaría 30 segundos las 10 veces.
Cuándo SÍ usar command:: cuando no existe un módulo dedicado para la tarea. Para esos casos, chequea primero el catálogo de collections oficiales, con cientos de módulos en ansible-core y miles más sumando todas las collections. Si no encuentras uno, recién ahí recurras a command o shell con creates o removes para simular idempotencia:
- name: Clonar repo si no existe
ansible.builtin.git:
repo: '[email protected]:mi-org/mi-app.git'
dest: /opt/mi-app
update: no
Módulos infrausados que te ahorran horas
Hay 3 módulos que aparecen poco en tutoriales pero resuelven problemas reales:
lineinfile: editar UNA línea de un archivo de configuración
El clásico “asegúrate que esta línea esté en /etc/ssh/sshd_config“. Lo contrario al antipatrón de reemplazar el archivo entero:
- name: Deshabilitar login root por SSH
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
state: present
notify: restart_sshd
regexp busca la línea existente (con o sin comentar), y line la reemplaza o la agrega al final si no existe. Cero riesgo de romper el resto del archivo.
package vs apt vs dnf
Si tu playbook corre en Debian, Ubuntu, Fedora y RHEL mezclados, package detecta el gestor de paquetes automáticamente:
- name: Instalar htop universal
ansible.builtin.package:
name: htop
state: present
Funciona en cualquier distro. Más portable que escribir tareas condicionales con when: ansible_os_family == 'Debian'.
assert: precondiciones que cortan el playbook
Antes de tocar nada, valida que el entorno cumple lo que asumís:
- name: Verificar versión mínima de Python
ansible.builtin.assert:
that:
- ansible_python_version is version('3.8', '>=')
fail_msg: "Este playbook requiere Python 3.8 o superior"
success_msg: "Python OK, continuando"
Si falla, Ansible aborta inmediatamente con el mensaje que pusiste. Mejor que enterarte a mitad del playbook que el servidor tiene Python 2.7.
Handlers: tareas que se ejecutan UNA sola vez al final
Un handler es una task que solo se dispara cuando otra task la notifica con notify. Sirve para evitar reiniciar un servicio 20 veces cuando 20 tareas diferentes cambian su configuración.
- hosts: webservers
tasks:
- name: Configurar virtualhost 1
ansible.builtin.template:
src: vhost1.conf.j2
dest: /etc/nginx/sites-enabled/vhost1.conf
notify: reload_nginx
- name: Configurar virtualhost 2
ansible.builtin.template:
src: vhost2.conf.j2
dest: /etc/nginx/sites-enabled/vhost2.conf
notify: reload_nginx
- name: Configurar virtualhost 3
ansible.builtin.template:
src: vhost3.conf.j2
dest: /etc/nginx/sites-enabled/vhost3.conf
notify: reload_nginx
handlers:
- name: reload_nginx
ansible.builtin.service:
name: nginx
state: reloaded
Ansible agrupa las notificaciones y corre el handler UNA vez al final del playbook, no una vez por cada cambio. Más eficiente y evita ventanas de downtime innecesarias.
Gotcha importante: si una task falla DESPUÉS de notificar al handler pero antes de que se ejecute el handler, el handler igual corre. Si eso te molesta, usa force_handlers: false en el play (es el default en algunas versiones pero no en todas, validalo).
Dynamic inventory: nodos que aparecen y desaparecen
El inventory estático (inventory.ini) sirve para 10 servidores fijos. Cuando tienes Proxmox, AWS, Hetzner o cualquier cloud con VMs que se crean y destruyen, el dynamic inventory lee la fuente de verdad en tiempo de ejecución.
Ejemplo con Hetzner Cloud:
plugin: hetzner.hcloud.hcloud_inventory
hcloud_api_token: "{{ vault_hcloud_token }}"
Cada vez que corres el playbook, Ansible consulta la API de Hetzner, obtiene la lista actual de servidores, y aplica las tareas a esa lista. Borrás una VM en el panel, y Ansible deja de intentar configurarla en el próximo run.
Para Proxmox existe community.general.proxmox y para AWS el amazon.aws.aws_ec2. La mayoría de providers grandes tienen su collection oficial en Ansible Galaxy.
Ansible-pull: nodos que se autoconfiguran
El flujo clásico es “control node empuja a los managed nodes”. ansible-pull invierte la dirección: cada nodo corre un cron que hace git pull de sus playbooks y los aplica localmente.
Útil para:
- Nodos detrás de NAT estricto donde no puedes llegar por SSH desde el control node
- Fleet grande donde no quieres mantener un inventario central
- Edge computing, IoT, kioskos
# En el nodo managed, vía SSH una sola vez para instalarlo:
sudo apt install ansible
sudo ansible-pull -U https://github.com/mi-org/ansible-pull-repo.git
-C main
playbook.yml
--vault-password-file /root/.vault_pass
Después lo agendás con cron cada 30 minutos:
echo '*/30 * * * * root /usr/bin/ansible-pull -U https://github.com/mi-org/ansible-pull-repo.git -C main playbook.yml --vault-password-file /root/.vault_pass'
| sudo tee /etc/cron.d/ansible-pull
Debugging: cómo entender qué está pasando
Tres flags que cambian todo cuando un playbook falla:
# Modo check: muestra QUÉ HARÍA sin tocar nada
ansible-playbook site.yml --check
# Modo diff: muestra QUÉ ARCHIVOS CAMBIARÍA línea por línea
ansible-playbook site.yml --check --diff
# Modo verbose: muestra la salida completa de los módulos
ansible-playbook site.yml -v # verbose básico
ansible-playbook site.yml -vv # más detalle
ansible-playbook site.yml -vvv # muestra también el comando SSH ejecutado
Para una task específica que falla, agregale debug: al lado para ver qué valores tienen las variables en ese momento:
- name: Verificar variable
ansible.builtin.debug:
var: vault_db_password
Cuidado: debug: var: imprime la variable en pantalla. Si es un secreto, mejor filtralo antes:
- name: Verificar variable sin imprimir el secreto
ansible.builtin.debug:
msg: "Usuario: {{ vault_db_user }}, Password length: {{ vault_db_password | length }}"
Cuándo NO usar Ansible
Ansible no es la herramienta correcta para todo. Reconocé cuándo escalar a otra cosa:
- Configuración de containers: si tu output es una imagen Docker o un chart de Helm, Ansible es el paso equivocado. usa Dockerfile + docker-compose, o Kubernetes manifests.
- Estado continuo de aplicación: Ansible es imperativo-declarativo y converge al estado, pero no se queda corriendo. Para mantener un proceso vivo y reaccionando a eventos (Kubernetes Pod, systemd watchdog), usa la herramienta nativa de la plataforma.
- Provisioning de infraestructura cloud nueva: Terraform o Pulumi están mejor diseñados para crear/destruir recursos. Ansible es mejor para configurar lo que ya existe.
- Fleet de 100+ nodos con cambios constantes: el modelo push empieza a mostrar limitaciones. mira SaltStack, Puppet o Ansible Automation Platform (AWX) con su modelo de control plane.
Resumen
Ansible sigue siendo la herramienta más práctica para sysadmins Linux que necesitan automatizar configuraciones en 5-50 servidores. Los puntos clave que vimos:
- Vault para secretos, sin excuses
- Idempotencia dura: usa módulos dedicados, no
command - Handlers para evitar reinicios redundantes
- Dynamic inventory cuando los nodos cambian seguido
- ansible-pull para nodos detrás de NAT o fleet grande
- –check –diff -vvv como trío de debugging obligatorio
Si ya tienes Ansible instalado y jugaste con playbooks básicos, este artículo cubre los huecos que el tutorial típico se saltea. Si recién empezás, el artículo introductorio te da el contexto que acá asumimos.
Preguntas frecuentes
¿Por qué Ansible para sysadmins: casos prácticos que no están en el tutorial 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 Ansible para sysadmins: casos prácticos?
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 Ansible para sysadmins: casos prácticos?
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 Ansible para sysadmins: casos prácticos 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 Ansible para sysadmins: casos prácticos?
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
- Guía Fedora 44: Novedades, Instalación y Upgrade para Sysadmins Linux
- Configura VLANs en Linux con nmcli: Guía paso a paso para sysadmins
- Protege tu SSH: Guía esencial para configurar Fail2ban en Linux
- Guía Definitiva: Configura Kubernetes con kubeadm en Ubuntu para Sysadmins Linux
- Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux
