Ansible: cómo automatizar tu Home Lab de principio a fin
Este post forma parte de la serie Home Lab Llevo un tiempo acumulando servicios. Tengo Home Assistant, AdGuard, Vaultwarden, N8N, Immich, Firefly III, Paperless NGX, SearXNG. Cada uno en su propio contenedor, actualizándose a su ritmo. Y llega el momento en que quieres actualizar el sistema operativo de todos los contenedores. O instalar un certificado SSL en todos. O cambiar una configuración en varios a la vez. ¿Entrar uno por uno? Ni hablar. Ahí entra Ansible.
Qué es Ansible
Ansible es una herramienta de automatización de código abierto. Defines el estado que quieres que tengan tus máquinas en archivos YAML y Ansible se encarga de aplicar ese estado. Solo eso. Lo mejor: no necesitas instalar nada en los servidores que gestionas. Solo SSH. Y tus LXCs ya tienen SSH.
Por qué existe
Cuando tienes 3 o 4 servidores, actualizar uno a uno es asumible. Cuando tienes 10, 15, 20… se convierte en un trabajo de tarde entera y en una fuente de errores. Ansible resuelve ese problema centralizando toda la automatización en un solo punto.
Características principales
Sin agente
Ansible se conecta por SSH. No necesitas instalar nada en los servidores que gestionas. Solo el nodo de control tiene Ansible instalado. El resto ni se entera.
Idempotente
Puedes ejecutar el mismo playbook varias veces y el resultado es siempre el mismo. Si algo ya está configurado, Ansible no lo toca. Si falta, lo instala. Sin sorpresas.
YAML
Los playbooks se escriben en YAML. Legible, fácil de aprender, fácil de mantener. Mi mujer puede leer un playbook sin saber programación y entender qué hace.
Inventario
El inventario define qué máquinas gestionas. Puedes organizarlas en grupos:
all:
children:
servers:
hosts:
proxmox:
ansible_host: 192.168.1.10
ansible_user: admin
nas:
ansible_host: 192.168.1.50
ansible_user: admin
containers:
hosts:
homeassistant:
ansible_host: 192.168.1.20
adguard:
ansible_host: 192.168.1.21
Módulos
Ansible tiene cientos de módulos para casi todo:
apt: gestionar paquetessystemd: gestionar serviciosfile: gestionar archivosshell: ejecutar comandosdocker_container: gestionar contenedorescopy: copiar archivostemplate: plantillas con variables
Comandos básicos
# Ejecutar un comando en todos los hosts
ansible all -m ping
# Ejecutar un playbook
ansible-playbook site.yml
# Ejecutar solo en un grupo
ansible-playbook update.yml --tags security
# Ejecutar en un host específico
ansible-playbook site.yml --limit nas
# Ver diferencias antes de aplicar
ansible-playbook site.yml --check --diff
Playbooks
Un playbook define las tareas a ejecutar:
---
- name: Actualizar todos los servidores
hosts: all
become: yes
tasks:
- name: Actualizar lista de paquetes
apt:
update_cache: yes
- name: Actualizar paquetes
apt:
upgrade: yes
- name: Reiniciar si es necesario
reboot:
when: ansible_facts['needs_reboot']
Roles
Los roles organizan tus playbooks en partes reutilizables:
roles/
common/
tasks/
handlers/
templates/
docker/
tasks/
defaults/
backup/
tasks/
Comparativa con alternativas
| Característica | Ansible | Puppet | Chef | SaltStack | Terraform |
|---|---|---|---|---|---|
| Precio | Gratis | 100-150 $/año | 142 $/nodo | 150 $/año | 20 $/mes |
| Código abierto | Sí | Parcial | Parcial | Parcial | Parcial |
| Tipo | Configuración | Configuración | Configuración | Configuración | Provisioning |
| Agente | No | Sí | Sí | Sí | No |
| Curva aprendizaje | Baja | Alta | Alta | Media | Baja |
| Uso en Home Lab | Ideal | Excesivo | Excesivo | Medio | Bueno |
Puppet
Puppet es potente pero requiere un servidor central (Puppet Master) y agente en cada nodo. Para un Home Lab es excesivo en todos los sentidos.
Chef
Chef requiere Ruby y agentes. Demasiado complejo para lo que necesitas si lo que gestionas es un Home Lab.
SaltStack
SaltStack está bien pero tiene curva de aprendizaje considerable. También requiere agente.
Terraform
Terraform es para provisioning, no para configuración. Sirve para crear máquinas, no para configurarlas después. Se complementa con Ansible: Terraform crea la infraestructura, Ansible la configura.
Cómo estructuro mi Home Lab con Ansible
La estructura de directorios que uso es esta:
homelab-ansible/
inventory/
hosts.yml
group_vars/
all.yml
containers.yml
playbooks/
update.yml
security.yml
backup.yml
roles/
common/
docker/
monitoring/
No es la más compleja del mundo, pero funciona. El inventario en hosts.yml define todas las máquinas organizadas en grupos. Las variables compartidas van en group_vars/. Los playbooks concretos van en playbooks/. Los roles reutilizables en roles/.
Lo primero que automaticé: las actualizaciones
El primer playbook que escribí fue de actualizaciones. No porque sea lo más impresionante, sino porque era lo que más tiempo me quitaba. Entrar a cada contenedor, hacer apt update && apt upgrade, salir, entrar al siguiente. Aburrido y propenso a olvidarme de alguno.
El playbook de actualizaciones hace exactamente eso en todos los contenedores a la vez:
---
- name: Actualizar todos los sistemas
hosts: all
become: yes
tasks:
- name: Actualizar lista de paquetes
apt:
update_cache: yes
cache_valid_time: 3600
- name: Actualizar todos los paquetes
apt:
upgrade: dist
autoremove: yes
autoclean: yes
- name: Comprobar si hace falta reiniciar
stat:
path: /var/run/reboot-required
register: reboot_required
- name: Reiniciar si es necesario
reboot:
msg: "Reiniciando para aplicar actualizaciones"
connect_timeout: 5
reboot_timeout: 300
when: reboot_required.stat.exists
Un comando: ansible-playbook playbooks/update.yml. Todos los contenedores actualizados, los que necesitan reinicio se reinician solos, los que no lo necesitan no lo hacen. Sin entrar a ninguno.
Lo segundo: hardening básico de seguridad
El segundo playbook fue de configuración de seguridad básica para contenedores nuevos. Cosas que hacía a mano cada vez que creaba un LXC nuevo y que era fácil olvidarse de alguna: deshabilitar login de root por SSH, instalar fail2ban, configurar reglas básicas de firewall.
---
- name: Hardening básico de seguridad
hosts: all
become: yes
tasks:
- name: Deshabilitar login root por SSH
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
state: present
notify: Reiniciar SSH
- name: Instalar fail2ban
apt:
name: fail2ban
state: present
- name: Activar fail2ban
systemd:
name: fail2ban
enabled: yes
state: started
handlers:
- name: Reiniciar SSH
systemd:
name: sshd
state: restarted
Ahora cuando creo un contenedor nuevo, ejecuto este playbook contra él y en dos minutos tiene la configuración de seguridad base aplicada. Sin acordarme de los pasos, sin saltarme ninguno.
Los comandos que más uso en el día a día
En el día a día, la mayoría de lo que hago con Ansible son variaciones de cuatro o cinco comandos:
# Comprobar que todos los hosts responden
ansible all -m ping
# Ver qué cambiaría sin aplicar nada todavía
ansible-playbook playbooks/update.yml --check --diff
# Ejecutar solo en un grupo
ansible-playbook playbooks/update.yml --limit containers
# Ejecutar una tarea suelta sin playbook
ansible all -m shell -a "df -h" --limit servers
El --check --diff antes de ejecutar cualquier cambio importante es un hábito que vale la pena coger desde el principio. Te muestra qué cambiaría sin cambiar nada. Cuando el playbook afecta a veinte máquinas, ver primero qué va a hacer antes de que lo haga da mucha tranquilidad.
Lo tercero: desplegar nuevos servicios
Tardé un poco más en llegar aquí, pero cuando lo hice fue la mayor diferencia. En lugar de seguir un tutorial paso a paso para instalar un servicio nuevo, escribo el playbook una vez y lo ejecuto. Si algo sale mal o necesito reinstalar desde cero, ejecuto el playbook de nuevo y queda exactamente igual. Tengo roles para Docker, para Nginx, para configurar certificados SSL. Cuando un servicio nuevo necesita esas piezas, las incluyo en su playbook y ya están.
Por qué elegí Ansible
La respuesta corta: porque funciona, es gratis y no necesita agentes. Puedo agrupar mis máquinas como quiera, por función, por entorno, por servidor padre. Hay playbooks y roles en la comunidad para casi todo lo que puedes necesitar en un Home Lab. Y cuando necesito algo que no existe, escribirlo en YAML es sencillo. Lo ejecuto, se aplica en todos los contenedores a la vez y ya está. Sin entrar uno por uno, sin olvidarme de ninguno.
Ejemplo real: actualizar todos los contenedores
# Actualizar un grupo específico
ansible-playbook -i inventory.yml update-containers.yml --limit containers
Playbook de ejemplo:
---
- name: Actualizar contenedores Docker
hosts: containers
become: yes
tasks:
- name: Actualizar contenedores
docker_container:
name: "{{ item.name }}"
image: "{{ item.image }}"
state: started
restart: yes
loop:
- { name: homeassistant, image: homeassistant/home-assistant:stable }
- { name: adguard, image: adguard/adguardhome:latest }
- { name: vaultwarden, image: vaultwarden/server:latest }
Un comando. Todos actualizados. Sin entrar a ninguno.
Instalación
En el nodo de control
# En Debian/Ubuntu
sudo apt update
sudo apt install ansible
# O con pip
pip install ansible
Configuración básica
- Crea tu directorio de proyecto
- Define tu inventario
- Escribe tus playbooks
- Ejecuta
mkdir ~/homelab-ansible
cd ~/homelab-ansible
ansible-init
Cuándo elegir qué
Elige Ansible si:
- Quieres gestionar configuración de servidores desde un solo punto
- Necesitas actualizar muchos sistemas a la vez
- No quieres instalar agentes en cada máquina
- Prefieres YAML
Elige Terraform si:
- Solo necesitas crear infraestructura
- Quieres gestionar máquinas como código, no configurarlas
Elige Puppet o Chef si:
- Trabajas en una empresa grande con equipos dedicados a ops
- Necesitas cumplimiento estricto y certificaciones
Compártelo si te ha resultado útil. ¿Gestionas ya tu Home Lab con alguna herramienta de automatización? Cuéntame qué usas. Si necesitas ayuda implementando esto en tu empresa, puedo ayudarte. Y… hasta aquí por hoy!
Artículos relacionados
Las razones por las que no uso los helper scripts de Proxmox
Explico por qué dejé de usar los helper scripts de Proxmox a favor de una arquitectura más robusta. Los scripts instalan bases de datos dentro de cada contenedor, generando desperdicio de RAM, mantenimiento complejo y backups difíciles. Te muestro cómo centralizar bases de datos en un servidor dedicado para ahorrar recursos y simplificar.
N8N: Tu automatización bajo tu control, sin pagos mensuales
N8N es una herramienta de automatización de flujo de trabajo de código abierto que puedes instalar en tu Home Lab. Automatiza tus tareas sin pagar mensualidades y sin depender de servicios externos. Te permite conectar diferentes servicios y aplicaciones para que trabajen juntas automáticamente. A diferencia de Zapier o Make que tienen límites de ejecuciones y cuestan dinero, N8N self-hosted te da potencia ilimitada sin facturas sorpresa. Tiene editor visual drag-and-drop, más de 400 integraciones, soporte para código personalizado en JavaScript o Python, nodos de Inteligencia Artificial con LangChain, OpenAI o Anthropic, y modo cola para escalar hasta 200 ejecuciones por segundo.
Vaultwarden: contraseñas seguras en tu servidor, sin pagos
Vaultwarden es una implementación ligera de Bitwarden escrita en Rust. Obtén todas las funcionalidades premium gratis: TOTP, archivos adjuntos y acceso de emergencia. Compatible con todos los clientes oficiales, cifrado del lado del cliente y tus datos en tu propio servidor.