Fundamentos de los Playbooks en Ansible
Los playbooks son archivos YAML que orquestan tareas de configuración y gestión en múltiples hosts. Su estructura permite definir secuencias de operaciones de forma declarativa, facilitando la adimnistración de sistemas complejos.
Componentes Esenciales de un Playbook
- Tareas (Tasks): Acciones unitarias ejecutadas en los hosts objetivo.
- Variables (Vars): Almacenan valores reutilizables para personalizar comportamientos.
- Plantillas (Templates): Archivos con marcadores que se renderizan mediante Jinja2.
- Manejadores (Handlers): Tareas invocadas únicamente cuando se notifican cambios.
- Roles: Estructuras modulares que encapsulan lógica reutilizable.
Ejemplo Práctico: Despliegue de Servicio Web
Este playbook configura un servidor Nginx con una página personalizada. Observa cómo se simplifica la lógica y se utilizan nombres descriptivos.
---
- name: Configurar servidor web
hosts: grupo_web
become: true
vars:
servicio: nginx
ruta_contenido: /var/www/html
tasks:
- name: Asegurar que el paquete está instalado
apt:
name: "{{ servicio }}"
state: latest
- name: Desplegar archivo de configuración
template:
src: configuracion_nginx.j2
dest: /etc/nginx/nginx.conf
notify: Reiniciar servicio
- name: Crear directorio raíz
file:
path: "{{ ruta_contenido }}"
state: directory
- name: Generar página de índice
copy:
content: "<h1>Servicio activo</h1>"
dest: "{{ ruta_contenido }}/index.html"
handlers:
- name: Reiniciar servicio
service:
name: "{{ servicio }}"
state: restarted
Para ejecutarlo: ansible-playbook despliegue_web.yml --syntax-check
Variables y Control de Flujo
Las variables pueden definirse en el playbook, en archivos externos o mediante la línea de comandos. Utilízalas para parametrizar configuraciones.
---
- name: Gestionar usuarios y grupos
hosts: todos_los_servidores
vars:
grupo_app: aplicacion
usuario_app: svc_account
uid_app: 2001
tasks:
- name: Verificar sistema operativo
debug:
msg: "Sistema: {{ ansible_distribution }}"
when: ansible_distribution == "Ubuntu"
- name: Crear grupo
group:
name: "{{ grupo_app }}"
state: present
- name: Crear usuario
user:
name: "{{ usuario_app }}"
uid: "{{ uid_app }}"
groups: "{{ grupo_app }}"
append: yes
Iteraciones y Tareas Condicionales
Los bucles permiten aplicar acciones a conjuntos de datos. Combínalos con condiciones para un control fino.
---
- name: Configurar entornos múltiples
hosts: localhost
gather_facts: false
vars:
entornos:
- nombre: produccion
ruta: /opt/prod
- nombre: desarrollo
ruta: /opt/dev
tasks:
- name: Crear estructura de directorios
file:
path: "{{ item.ruta }}/logs"
state: directory
loop: "{{ entornos }}"
when: item.nombre == "produccion"
- name: Establecer permisos
file:
path: "{{ item.ruta }}"
owner: root
mode: '0755'
loop: "{{ entornos }}"
Módulos Avanzados para Playbooks
Plantillas con Jinja2
Las plantillas permiten generar archivos dinámicamente. Define variables específicas por host en el inventario.
# Archivo: plantilla_nginx.j2
server {
listen {{ puerto_escucha }};
server_name {{ nombre_servidor }};
root {{ directorio_raiz }};
location / {
try_files $uri $uri/ =404;
}
}
En el inventario (/etc/ansible/hosts):
[grupo_web]
192.168.1.10 puerto_escucha=80 nombre_servidor=app.ejemplo.com directorio_raiz=/var/www/app
192.168.1.11 puerto_escucha=8080 nombre_servidor=app2.ejemplo.com directorio_raiz=/var/www/app2
Uso de Tags para Ejecución Selectiva
Los tags permiten ejecutar solo partes específicas de un playbook. La etiqueta always garantiza ejecución incondicional.
---
- name: Tareas con etiquetas
hosts: todos
tasks:
- name: Actualizar repositorios
apt:
update_cache: yes
tags: [actualizaciones, siempre]
- name: Instalar herramientas de monitoreo
apt:
name: htop
state: present
tags: monitoreo
Ejecución: ansible-playbook tareas.yml --tags monitoreo
Organización con Roles
Los roles promueven la reutilización y modularidad. Su estructura estándar facilita la gestión de configuraciones complejas.
Estructura de un Rol
/etc/ansible/roles/
└── rol_aplicacion/
├── tasks/main.yml # Tareas principales
├── handlers/main.yml # Manejadores de eventos
├── templates/ # Plantillas Jinja2
├── files/ # Archivos estáticos
├── vars/main.yml # Variables del rol
├── defaults/main.yml # Valores por defecto
└── meta/main.yml # Dependencias y metadatos
Aplicación Práctica: Despliegue de Pila LEMP
Implementación de un entorno Linux, Nginx, MySQL y PHP utilizando roles independientes.
Rol para Nginx
# roles/nginx/tasks/main.yml
- name: Instalar Nginx
apt:
name: nginx
state: present
- name: Habilitar servicio
service:
name: nginx
enabled: yes
state: started
# roles/nginx/vars/main.yml
nombre_paquete: nginx
nombre_servicio: nginx
Rol para MySQL
# roles/mysql/tasks/main.yml
- name: Instalar servidor MySQL
apt:
name: "{{ item }}"
state: present
loop:
- mysql-server
- python3-mysqldb
- name: Configurar servicio
service:
name: mysql
state: started
enabled: yes
Playbook Orquestador
---
- name: Desplegar pila completa LEMP
hosts: servidores_web
become: true
roles:
- nginx
- mysql
- php-fpm
Este enfoque modular permite actualizar componentes individuales sin afectar el conjunto.