intermediate Por Mathias Paulenko

Playbook de Ansible para Configuración de Servidores

Cómo escribir y ejecutar playbooks de Ansible para provisionar, configurar y gestionar servidores con tareas idempotentes, roles y archivos de inventario.

Temas: devops

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Descripción General

Ansible es una herramienta de automatización sin agentes que utiliza playbooks YAML para configurar servidores, desplegar aplicaciones y orquestar infraestructura. A diferencia de herramientas que requieren un daemon en cada host objetivo, Ansible se conecta por SSH y ejecuta tareas remotamente, siendo ligero y fácil de adoptar.

Antes de las herramientas de configuration management, los sysadmins se conectaban manualmente a cada servidor para instalar paquetes, editar archivos de configuración y reiniciar servicios. Esto era lento, propenso a errores e imposible de auditar. Ansible reemplaza esto con playbooks declarativos e idempotentes que pueden configurar cientos de servidores en minutos y versionarse como código de aplicación.

Cuándo Usar

Usa esta receta cuando:

  • Provisionas nuevos servidores con una línea base consistente (paquetes, usuarios, claves SSH).
  • Despliegas actualizaciones de aplicación a través de múltiples servidores web en paralelo.
  • Aseguras que todos los nodos de producción comparten la misma configuración (Nginx, PostgreSQL, Redis).
  • Ejecutas comandos ad-hoc en toda una flota (ej., reiniciar todos los servicios después de un parche de seguridad).
  • Manejas secrets con Ansible Vault en lugar de hardcodear contraseñas en playbooks.

Lo que funciona

  • Haz las tareas idempotentes. Ejecutar un playbook dos veces no debería cambiar nada en la segunda ejecución. Usa state: present en lugar de comandos shell que instalan paquetes ciegamente.
  • Usa roles para reutilización. Extrae tareas comunes en roles que pueden compartirse entre proyectos y equipos vía Ansible Galaxy o un repositorio Git privado.
  • Versiona todo. Playbooks, inventarios y variables deben vivir en git para que los cambios sean peer-reviewed y reversibles.
  • Usa ansible-lint para forzar estilo y detectar errores comunes antes de ejecutar playbooks en producción.
  • Encripta secrets con Ansible Vault en lugar de almacenar contraseñas en texto plano. Nunca commitees credenciales sin encriptar.

Errores Comunes

  • Ejecutar playbooks sin --check primero en infraestructura de producción. El modo check revela qué cambiaría sin realizar los cambios.
  • Usar tareas shell o command cuando existe un módulo dedicado. Los módulos son idempotentes y manejan mejor los casos de error que comandos shell crudos.
  • Olvidar become: yes cuando las tareas requieren privilegios de root, causando errores de permisos crípticos.
  • Hardcodear direcciones IP en archivos de inventario. Usa nombres DNS o scripts de inventario dinámico (AWS, GCP) que se mantengan actualizados a medida que la infraestructura escala.
  • No usar handlers para reinicios de servicios. Un playbook que reinicia Nginx en cada tarea es innecesario; los handlers solo se disparan una vez al final cuando son notificados.

Errores Comunes Adicionales

  1. No cachear facts. La recolección de facts es lenta en muchos hosts:
# ansible.cfg
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = ./.facts
fact_caching_timeout = 86400
  1. Ejecutar todo como root. Usa become selectivamente por tarea:
# Mal: todo corre como root
- hosts: all
  become: yes
  tasks:
    - name: Clonar repo como root
      ansible.builtin.git:
        repo: https://github.com/myorg/myapp.git
        dest: /home/deployer/myapp

# Bien: become solo donde es necesario
- hosts: all
  tasks:
    - name: Instalar paquetes
      ansible.builtin.apt:
        name: nginx
        state: present
      become: yes

    - name: Clonar repo como deployer
      ansible.builtin.git:
        repo: https://github.com/myorg/myapp.git
        dest: /home/deployer/myapp
      become: yes
      become_user: deployer
  1. No usar --diff para auditoría. Ve exactamente qué cambia en cada ejecución:
ansible-playbook site.yml --diff

Tips de Rendimiento

  1. Usa strategy: free para ejecución más rápida. Cada host corre independientemente:
- name: Despliegue paralelo rápido
  hosts: webservers
  strategy: free
  tasks:
    - name: Desplegar app
      ansible.builtin.git:
        repo: https://github.com/myorg/myapp.git
        dest: /var/www/myapp
  1. Deshabilita la recolección de facts cuando no se usa. Ahorra 2-5 segundos por host:
- name: Tarea simple sin facts
  hosts: webservers
  gather_facts: no
  tasks:
    - name: Reiniciar servicio
      ansible.builtin.service:
        name: nginx
        state: restarted
  1. Usa async para tareas long-running. No bloquees el playbook:
- name: Ejecutar backup lento
  ansible.builtin.shell: pg_dump mydb > /tmp/backup.sql
  async: 300
  poll: 5

Preguntas frecuentes

¿Cuál es la ventaja de Ansible sobre scripts de shell?
Los playbooks de Ansible son idempotentes y declarativos. Ejecutar el mismo playbook dos veces produce el mismo estado sin duplicar configuración ni causar errores.
¿Cómo manejo secretos en Ansible?
Usa Ansible Vault para cifrar archivos sensibles, o intégralo con gestores de secretos externos como HashiCorp Vault o AWS Secrets Manager. Nunca commitees contraseñas en texto plano.
¿Qué es un inventario de Ansible?
Un inventario lista los hosts gestionados y los agrupa lógicamente (por ejemplo, web, db, cache). Los inventarios pueden ser archivos estáticos o plugins dinámicos obtenidos de proveedores cloud.