La automatización de infraestructuras críticas requiere herramientas robustas que garanticen consistencia y alta disponibilidad. A continuación, se describe el procedimiento para desplegar un cluster web utilizando Ansible, integrando Nginx como balanceador de carga, Tomcat para la ejecución de aplicaciones Java y Keepalived para la gestión de IPs virtuales (VIP).
Estructura de Directorios del Proyecto
La organización de los roles sigue el estándar de Ansible, separando claramente las tareas, variables, plantillas y archivos estáticos para cada componente.
roles/
├── keepalived
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── keepalived_master.cfg.j2
│ │ └── keepalived_backup.cfg.j2
│ └── vars
│ └── main.yml
├── nginx
│ ├── files
│ │ ├── nginx-source.tar.gz
│ │ └── nginx_unit.service
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ └── nginx_main.conf.j2
│ └── vars
│ └── main.yml
├── tomcat
│ ├── files
│ │ ├── jdk_installer.gz
│ │ └── tomcat_binary.tar.gz
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── env_java.sh.j2
│ │ ├── catalina_env.sh.j2
│ │ └── tomcat_unit.service.j2
│ └── vars
│ └── main.yml
└── site_playbook.yml
Playbook Principal de Despliegue
El archivo site_playbook.yml orquesta la ejecución de los roles sobre los grupos de inventario definidos. Se separan los nodos balanceadores de los servidores de aplicación.
---
- name: Despliegue de Balanceadores
hosts: balanceadores
become: true
roles:
- nginx
- keepalived
- name: Despliegue de Servidores de Aplicación
hosts: aplicacion
become: true
roles:
- tomcat
Configuración del Rol Nginx
Este rol se encarga de compilar Nginx desde el código fuente e integrar la configuración de balanceo hacia los backend.
Tareas Principales (tasks/main.yml)
- name: Instalar dependencias de compilación
ansible.builtin.package:
name: "{{ paquetes_compilacion }}"
state: installed
- name: Extraer código fuente de Nginx
ansible.builtin.unarchive:
src: nginx-source.tar.gz
dest: /tmp/
creates: /tmp/nginx-{{ version_nginx }}
- name: Compilar e instalar Nginx
ansible.builtin.shell: |
./configure --prefix={{ ruta_instalacion_nginx }} --with-http_ssl_module
make && make install
args:
chdir: /tmp/nginx-{{ version_nginx }}
tags:
- compilar
- name: Desplegar unidad systemd
ansible.builtin.copy:
src: nginx_unit.service
dest: /etc/systemd/system/nginx.service
- name: Recargar daemon de systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Generar configuración principal
ansible.builtin.template:
src: nginx_main.conf.j2
dest: {{ ruta_instalacion_nginx }}/conf/nginx.conf
notify:
- reiniciar_nginx
- name: Habilitar e iniciar servicio
ansible.builtin.service:
name: nginx
state: started
enabled: true
Manejadores (handlers/main.yml)
- name: reiniciar_nginx
ansible.builtin.service:
name: nginx
state: reloaded
Variables (vars/main.yml)
version_nginx: "1.16.0"
ruta_instalacion_nginx: "/opt/nginx"
paquetes_compilacion:
- gcc
- openssl-devel
- zlib-devel
- pcre-devel
backend_1: "192.168.10.5:8080"
backend_2: "192.168.10.6:8080"
Plantilla de Configuración (templates/nginx_main.conf.j2)
worker_processes {{ ansible_processor_vcpus }};
events {
worker_connections 2048;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 70;
upstream cluster_tomcat {
server {{ backend_1 }};
server {{ backend_2 }};
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://cluster_tomcat;
proxy_set_header Host $host;
}
}
}
Configuración del Rol Tomcat
Este rol prepara el entorno Java y despliega el contenedor de servlets, configurando las variables de entorno necesarias para su ejecución como servicio.
Tareas Principales (tasks/main.yml)
- name: Descomprimir JDK
ansible.builtin.unarchive:
src: jdk_installer.gz
dest: /opt/
- name: Crear enlace simbólico Java
ansible.builtin.file:
src: /opt/jdk1.8.0_144
path: {{ ruta_java_home }}
state: link
- name: Configurar variables de entorno globales
ansible.builtin.template:
src: env_java.sh.j2
dest: /etc/profile.d/java_env.sh
- name: Descomprimir Tomcat
ansible.builtin.unarchive:
src: tomcat_binary.tar.gz
dest: /opt/
- name: Crear enlace simbólico Tomcat
ansible.builtin.file:
src: /opt/apache-tomcat-8.5.37
path: {{ ruta_tomcat_home }}
state: link
- name: Ajustar script de clase Java
ansible.builtin.template:
src: catalina_env.sh.j2
dest: {{ ruta_tomcat_home }}/bin/setclasspath.sh
- name: Instalar unidad systemd para Tomcat
ansible.builtin.template:
src: tomcat_unit.service.j2
dest: /etc/systemd/system/tomcat.service
- name: Activar e iniciar Tomcat
ansible.builtin.service:
name: tomcat
state: started
enabled: true
Variables (vars/main.yml)
ruta_java_home: "/opt/java"
ruta_tomcat_home: "/opt/tomcat"
Servicio Systemd (templates/tomcat_unit.service.j2)
[Unit]
Description=Servidor de Aplicaciones Apache Tomcat
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME={{ ruta_java_home }}
ExecStart={{ ruta_tomcat_home }}/bin/startup.sh
ExecStop={{ ruta_tomcat_home }}/bin/shutdown.sh
User=root
[Install]
WantedBy=multi-user.target
Configuración del Rol Keepalived
Keepalived gestiona la IP flotante. La configuración diferancia entre nodo maestro y respaldo mediante variables dinámicas.
Tareas Principales (tasks/main.yml)
- name: Instalar paquete Keepalived
ansible.builtin.package:
name: keepalived
state: installed
- name: Desplegar configuración según rol
ansible.builtin.template:
src: "{{ archivo_configuracion_keepalived }}"
dest: /etc/keepalived/keepalived.conf
notify:
- reiniciar_keepalived
- name: Asegurar estado del servicio
ansible.builtin.service:
name: keepalived
state: started
enabled: true
Variables Condicionales (vars/main.yml)
Se utiliza una variable tipo_nodo_ha definida en el inventario para seleccionar la plantilla adecuada.
vip_flotante: "192.168.10.100"
id_router_maestro: "MASTER_NODE"
id_router_respaldo: "BACKUP_NODE"
prioridad_maestro: 100
prioridad_respaldo: 90
Plantilla Maestro (templates/keepalived_master.cfg.j2)
vrrp_instance VI_Cluster {
state MASTER
interface {{ ansible_default_ipv4.alias }}
virtual_router_id 51
priority {{ prioridad_maestro }}
advert_int 1
authentication {
auth_type PASS
auth_pass secret_ha
}
virtual_ipaddress {
{{ vip_flotante }}
}
}
Plantilla Respaldo (templates/keepalived_backup.cfg.j2)
vrrp_instance VI_Cluster {
state BACKUP
interface {{ ansible_default_ipv4.alias }}
virtual_router_id 51
priority {{ prioridad_respaldo }}
advert_int 1
authentication {
auth_type PASS
auth_pass secret_ha
}
virtual_ipaddress {
{{ vip_flotante }}
}
}
Manejadores (handlers/main.yml)
- name: reiniciar_keepalived
ansible.builtin.service:
name: keepalived
state: restarted