
Administrar decenas o cientos de servidores manualmente puede convertirse rápidamente en una tarea complicada. Ejecutar un comando mediante SSH en un servidor es sencillo; ejecutarlo de manera controlada sobre 100 servidores es otro problema completamente diferente.
Aquí es donde Ansible se convierte en una herramienta extremadamente útil para administradores Linux, ingenieros DevOps, SRE y equipos de Production Support.
En este artículo veremos algunos de los comandos de Ansible que más utilizo o considero útiles para tareas administrativas sobre un inventario de aproximadamente 100 hosts Linux, organizándolos por módulos y tipo de actividad administrativa.
1. Preparando el inventario
Supongamos que tenemos 100 servidores distribuidos entre servidores web, aplicaciones y bases de datos.
Nuestro archivo inventory.ini podría tener esta estructura:
[webservers]
web01
web02
web03
...
web30
[appservers]
app01 app02 app03 … app50
[databases]
db01 db02 db03 … db20
Tenemos:
30 Web Servers
50 Application Servers
20 Database Servers
-----------------------
100 Hosts
Podemos verificar cómo interpreta Ansible nuestro inventario:
ansible-inventory -i inventory.ini --graph
Para obtener todos los detalles:
ansible-inventory -i inventory.ini --list
Y para consultar un host determinado:
ansible-inventory -i inventory.ini --host app01
2. Módulo ping — comprobar conectividad
Antes de realizar cualquier actividad sobre 100 servidores, normalmente lo primero que debemos hacer es verificar que Ansible pueda conectarse correctamente.
ansible all -i inventory.ini -m ansible.builtin.ping
Una respuesta correcta será similar a:
app01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Es importante recordar que ansible.builtin.ping no ejecuta un ICMP ping tradicional.
Ansible intenta conectarse al servidor y comprobar que existe un entorno Python utilizable.
Comprobar únicamente servidores de aplicaciones
ansible appservers -i inventory.ini -m ansible.builtin.ping
Conectar con otro usuario
ansible all -i inventory.ini -u ansible -m ansible.builtin.ping
Utilizar sudo
ansible all -i inventory.ini -u ansible --become \
-m ansible.builtin.ping
Esta es una excelente comprobación previa antes de iniciar patching, reinicios o cambios importantes.
3. Módulo command — ejecutar comandos Linux
ansible.builtin.command probablemente sea uno de los módulos más utilizados durante actividades de soporte.
Por ejemplo, obtener el uptime de los 100 servidores:
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "uptime"
Consultar memoria:
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "free -m"
Consultar versión del kernel:
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "uname -r"
Verificar filesystem:
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "df -h"
Comprobar procesos Java:
ansible appservers -i inventory.ini \
-m ansible.builtin.command \
-a "pgrep -a java"
El módulo command debe utilizarse cuando únicamente necesitamos ejecutar un programa o comando.
Para pipes, redirecciones y otras funciones del shell utilizaremos el módulo shell.
4. Módulo shell — troubleshooting avanzado
El módulo:
ansible.builtin.shell
permite utilizar pipes, variables, redirecciones y otras características del shell.
Por ejemplo, encontrar filesystems superiores al 80%:
ansible all -i inventory.ini \
-m ansible.builtin.shell \
-a "df -P | awk 'NR>1 && \$5+0 > 80 {print}'"
Buscar procesos Java:
ansible appservers -i inventory.ini \
-m ansible.builtin.shell \
-a "ps -ef | grep java | grep -v grep"
Consultar los procesos que consumen más memoria:
ansible all -i inventory.ini \
-m ansible.builtin.shell \
-a "ps aux --sort=-%mem | head"
Consultar puertos escuchando:
ansible all -i inventory.ini \
-m ansible.builtin.shell \
-a "ss -lntp"
Buscar archivos grandes:
ansible all -i inventory.ini \
-m ansible.builtin.shell \
-a "find /var -type f -size +1G -ls 2>/dev/null"
Este módulo es especialmente útil durante troubleshooting de incidentes.
5. Módulo setup — obtener información de los servidores
Ansible puede recolectar automáticamente información del sistema mediante:
ansible.builtin.setup
Para obtener todos los facts:
ansible all -i inventory.ini \
-m ansible.builtin.setup
Sin embargo, para 100 servidores la información puede ser enorme.
Es mejor utilizar filtros.
Obtener sistema operativo
ansible all -i inventory.ini \
-m ansible.builtin.setup \
-a "filter=ansible_distribution*"
Obtener memoria
ansible all -i inventory.ini \
-m ansible.builtin.setup \
-a "filter=ansible_memtotal_mb"
Obtener procesadores
ansible all -i inventory.ini \
-m ansible.builtin.setup \
-a "filter=ansible_processor*"
Obtener direcciones IP
ansible all -i inventory.ini \
-m ansible.builtin.setup \
-a "filter=ansible_default_ipv4"
Esto resulta particularmente útil para inventarios, auditorías y troubleshooting.
6. Módulo service — administrar servicios
En Production Support constantemente necesitamos verificar, iniciar, detener o reiniciar servicios.
Para comprobar operaciones sobre Apache:
ansible webservers -i inventory.ini \
--become \
-m ansible.builtin.service \
-a "name=httpd state=started"
Reiniciar servicio
ansible webservers -i inventory.ini \
--become \
-m ansible.builtin.service \
-a "name=httpd state=restarted"
Detener servicio
ansible webservers -i inventory.ini \
--become \
-m ansible.builtin.service \
-a "name=httpd state=stopped"
Habilitar el servicio durante el boot
ansible webservers -i inventory.ini \
--become \
-m ansible.builtin.service \
-a "name=httpd state=started enabled=yes"
Esto puede utilizarse igualmente para servicios de middleware, agentes de monitorización u otros componentes.
7. Módulo systemd_service — servidores Linux con systemd
Cuando sabemos que nuestros servidores utilizan systemd podemos utilizar:
ansible.builtin.systemd_service
Por ejemplo:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.systemd_service \
-a "name=myapp state=restarted"
Recargar configuración de systemd:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.systemd_service \
-a "daemon_reload=true"
Consultar el estado:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.command \
-a "systemctl status myapp"
8. Módulo package — instalación y patching
Una de las principales ventajas de Ansible es poder realizar mantenimiento sobre muchos servidores simultáneamente.
Para instalar un paquete:
ansible all -i inventory.ini \
--become \
-m ansible.builtin.package \
-a "name=vim state=present"
Actualizar un paquete:
ansible all -i inventory.ini \
--become \
-m ansible.builtin.package \
-a "name=openssl state=latest"
Eliminarlo:
ansible all -i inventory.ini \
--become \
-m ansible.builtin.package \
-a "name=telnet state=absent"
Para servidores Red Hat/Oracle Linux también podemos utilizar módulos específicos del gestor de paquetes cuando necesitemos funcionalidades adicionales.
9. Módulo reboot — reinicios controlados
Durante actividades de patching normalmente será necesario reiniciar algunos servidores.
En lugar de ejecutar simplemente:
reboot
podemos utilizar el módulo dedicado:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.reboot
Por ejemplo:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.reboot \
-a "reboot_timeout=600"
La ventaja es que Ansible puede esperar hasta que el servidor vuelva a estar disponible.
10. Módulo copy — distribuir archivos a 100 servidores
Supongamos que necesitamos distribuir un archivo de configuración.
ansible all -i inventory.ini \
--become \
-m ansible.builtin.copy \
-a "src=application.conf dest=/etc/application.conf"
También podemos establecer permisos:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.copy \
-a "src=application.conf dest=/opt/app/application.conf owner=appuser group=appgroup mode=0644"
Un uso habitual sería distribuir:
Configuraciones
Certificados
Scripts
Agentes
Archivos de propiedades
Configuraciones de monitoreo
Para configuraciones dinámicas y reutilizables normalmente será mejor utilizar templates y playbooks.
11. Módulo file — permisos, directorios y archivos
Crear un directorio en los servidores:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.file \
-a "path=/opt/application/logs state=directory owner=appuser group=appgroup mode=0755"
Modificar permisos:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.file \
-a "path=/opt/application/start.sh mode=0755"
Eliminar un archivo:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.file \
-a "path=/tmp/old_file.log state=absent"
12. Módulo fetch — recolectar logs
Esta función resulta extremadamente útil para Production Support.
Supongamos que necesitamos descargar un log desde los servidores:
ansible appservers -i inventory.ini \
-m ansible.builtin.fetch \
-a "src=/var/log/messages dest=./logs/"
Ansible almacenará los archivos manteniendo información del host correspondiente.
Podemos utilizar este mecanismo para recolectar rápidamente evidencia de diferentes servidores durante un incidente.
13. Módulo user — administración de usuarios
Crear un usuario:
ansible all -i inventory.ini \
--become \
-m ansible.builtin.user \
-a "name=monitor state=present"
Eliminarlo:
ansible all -i inventory.ini \
--become \
-m ansible.builtin.user \
-a "name=monitor state=absent"
Agregar un usuario a un grupo:
ansible all -i inventory.ini \
--become \
-m ansible.builtin.user \
-a "name=appuser groups=application append=yes"
14. Ejecutar comandos en paralelo
Cuando administramos 100 hosts resulta importante controlar el paralelismo.
Ansible utiliza la opción:
--forks
o:
-f
Por ejemplo:
ansible all -i inventory.ini \
-m ansible.builtin.ping \
-f 20
Esto permite procesar hasta 20 hosts simultáneamente.
Para una consulta sencilla:
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "uptime" \
-f 20
No siempre debemos utilizar el máximo paralelismo posible.
En tareas sensibles como reinicios de clústeres, bases de datos o middleware es mejor controlar cuidadosamente cuántos servidores se procesan simultáneamente.
15. Ejecutar solamente contra determinados servidores
Esta capacidad es fundamental cuando administramos grandes inventarios.
Por ejemplo, solamente servidores web:
ansible webservers -i inventory.ini -m ansible.builtin.ping
Solamente application servers:
ansible appservers -i inventory.ini -m ansible.builtin.ping
Excluir un servidor:
ansible 'appservers:!app01' \
-i inventory.ini \
-m ansible.builtin.ping
Ejecutar contra dos grupos:
ansible 'webservers:appservers' \
-i inventory.ini \
-m ansible.builtin.ping
Ejecutar contra hosts determinados:
ansible 'app01:app02:app03' \
-i inventory.ini \
-m ansible.builtin.ping
16. Comprobar cambios antes de ejecutarlos
En producción siempre debemos intentar reducir el riesgo.
Algunos módulos soportan:
--check
Por ejemplo:
ansible appservers -i inventory.ini \
--become \
-m ansible.builtin.copy \
-a "src=application.conf dest=/etc/application.conf" \
--check
Esto permite comprobar qué cambios intentaría realizar Ansible sin aplicarlos.
No todos los módulos y comandos pueden simular completamente una operación, por lo que --check nunca debe sustituir nuestros procedimientos de cambio, pruebas y respaldos.
17. Ejecutar Playbooks
Los comandos ad hoc son excelentes para diagnóstico y tareas puntuales.
Para operaciones repetibles debemos utilizar Playbooks.
Ejecutar uno:
ansible-playbook -i inventory.ini maintenance.yml
Limitarlo solamente a application servers:
ansible-playbook -i inventory.ini maintenance.yml \
--limit appservers
Limitarlo a un servidor:
ansible-playbook -i inventory.ini maintenance.yml \
--limit app01
Simular cambios:
ansible-playbook -i inventory.ini maintenance.yml \
--check
Ver qué hosts serán afectados:
ansible-playbook -i inventory.ini maintenance.yml \
--list-hosts
Ver las tareas:
ansible-playbook -i inventory.ini maintenance.yml \
--list-tasks
18. Ejemplo real: revisión de 100 servidores antes de mantenimiento
Antes de una ventana de mantenimiento podríamos ejecutar varias comprobaciones.
1. Verificar conectividad
ansible all -i inventory.ini \
-m ansible.builtin.ping
2. Verificar uptime
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "uptime"
3. Revisar filesystem
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "df -h"
4. Revisar memoria
ansible all -i inventory.ini \
-m ansible.builtin.command \
-a "free -m"
5. Revisar aplicaciones
ansible appservers -i inventory.ini \
-m ansible.builtin.shell \
-a "ps -ef | grep java | grep -v grep"
6. Ejecutar mantenimiento
ansible-playbook -i inventory.ini maintenance.yml
7. Verificar conectividad nuevamente
ansible all -i inventory.ini \
-m ansible.builtin.ping
8. Verificar aplicaciones
ansible appservers -i inventory.ini \
-m ansible.builtin.command \
-a "systemctl status myapp"
Con estas operaciones podemos realizar una validación pre-check → mantenimiento → post-check sobre decenas o cientos de servidores.
19. Cheat sheet
# Inventario
ansible-inventory -i inventory.ini --graph
# Conectividad
ansible all -i inventory.ini -m ansible.builtin.ping
# Uptime
ansible all -i inventory.ini -m ansible.builtin.command -a "uptime"
# Filesystem
ansible all -i inventory.ini -m ansible.builtin.command -a "df -h"
# Memoria
ansible all -i inventory.ini -m ansible.builtin.command -a "free -m"
# Facts
ansible all -i inventory.ini -m ansible.builtin.setup
# Procesos
ansible all -i inventory.ini -m ansible.builtin.shell -a "ps -ef"
# Reiniciar servicio
ansible appservers -i inventory.ini --become \
-m ansible.builtin.service -a "name=myapp state=restarted"
# Copiar archivo
ansible all -i inventory.ini \
-m ansible.builtin.copy \
-a "src=file.conf dest=/tmp/file.conf"
# Crear directorio
ansible all -i inventory.ini \
-m ansible.builtin.file \
-a "path=/opt/application state=directory"
# Reboot
ansible appservers -i inventory.ini \
--become -m ansible.builtin.reboot
# Playbook
ansible-playbook -i inventory.ini maintenance.yml
# Limitar hosts
ansible-playbook -i inventory.ini maintenance.yml --limit appservers
# Simulación
ansible-playbook -i inventory.ini maintenance.yml --check
Conclusión
Cuando administramos 100 servidores, Ansible deja de ser simplemente una herramienta DevOps y se convierte en una herramienta de operación.
Un administrador puede pasar de conectarse manualmente mediante SSH a decenas de servidores a ejecutar una misma comprobación de manera centralizada, consistente y repetible.
Para tareas puntuales, los comandos ad hoc son extraordinariamente útiles. Para actividades repetitivas como patching, failover, reinicios de clúster, deployments o mantenimiento programado, es mucho mejor convertir esas operaciones en Playbooks reutilizables.
El verdadero beneficio de Ansible no consiste solamente en ejecutar un comando en 100 máquinas.
Consiste en conseguir que 100 máquinas reciban una operación controlada, repetible y verificable desde un único punto de administración.
