Despliegue automático de una infraestructura web con balanceador Nginx y alta disponibilidad en la nube con Ansible
¿Te imaginas desplegar una infraestructura web resiliente, con balanceo de carga y alta disponibilidad en la nube, en cuestión de minutos? Hoy te presento un playbook de Ansible que te permitirá crear, desde cero, una arquitectura moderna compuesta por:
- Una instancia Nginx actuando como balanceador de carga.
- Dos instancias backend con servidor web Apache.
- Configuración automática del archivo de inventario dinámico para descubrir los hosts en la nube.
- Opcional: Podrás adaptarlo fácilmente a tu proveedor cloud preferido (ejemplo usando AWS EC2).
¿Por qué es útil este playbook?
Automatizar el despliegue de una arquitectura web escalable y tolerante a fallos es esencial para entornos de producción y pruebas rápidas. Te ayudará a ahorrar horas de configuración manual, reducir errores y asegurar que cada entorno es idéntico y reproducible gracias al poder de Ansible y sus módulos para la nube (como amazon.aws.ec2
o community.aws.ec2_instance
)[3].
Playbook completo: Infraestructura Web Balanceada y HA
---
- name: Infraestructura web balanceada y altamente disponible en la nube
hosts: localhost
gather_facts: false
vars:
region: "eu-west-1"
image_id: "ami-0c55b159cbfafe1f0" # Ubuntu 22.04, verifica el ID según tu región
instance_type: "t2.micro"
key_name: "tu-clave-aws"
security_group: "web-ansible-sg"
backend_count: 2
tasks:
- name: Crear security group
amazon.aws.ec2_group:
name: "{{ security_group }}"
description: "Habilita http y ssh desde cualquier sitio"
region: "{{ region }}"
rules:
- proto: tcp
ports:
- 22
- 80
cidr_ip: 0.0.0.0/0
rules_egress:
- proto: -1
cidr_ip: 0.0.0.0/0
state: present
register: group_info
- name: Lanzar instancias de backends Apache
amazon.aws.ec2:
key_name: "{{ key_name }}"
group: "{{ security_group }}"
image: "{{ image_id }}"
wait: true
instance_type: "{{ instance_type }}"
region: "{{ region }}"
count: "{{ backend_count }}"
instance_tags:
Role: "backend"
register: ec2_backend
- name: Lanzar instancia balanceador Nginx
amazon.aws.ec2:
key_name: "{{ key_name }}"
group: "{{ security_group }}"
image: "{{ image_id }}"
wait: true
instance_type: "{{ instance_type }}"
region: "{{ region }}"
count: 1
instance_tags:
Role: "balancer"
register: ec2_balancer
- name: Esperar a que los backends estén accesibles por SSH
ansible.builtin.wait_for:
host: "{{ item.public_ip }}"
port: 22
delay: 10
timeout: 300
with_items: "{{ ec2_backend.instances }}"
delegate_to: localhost
- name: Esperar a que el balanceador esté accesible por SSH
ansible.builtin.wait_for:
host: "{{ ec2_balancer.instances[0].public_ip }}"
port: 22
delay: 10
timeout: 300
delegate_to: localhost
- name: Añadir hosts al inventario dinámico en memoria
add_host:
name: "{{ item.public_ip }}"
groups: "backends"
with_items: "{{ ec2_backend.instances }}"
- name: Añadir balanceador al inventario
add_host:
name: "{{ ec2_balancer.instances[0].public_ip }}"
groups: "balancer"
- name: Instalar Apache en backends
hosts: backends
become: true
tasks:
- name: Instalar Apache2
apt:
name: apache2
state: present
update_cache: yes
- name: Personalizar página index.html
copy:
dest: /var/www/html/index.html
content: |
Soy un Backend Apache - {{ inventory_hostname }}
- name: Instalar y configurar Nginx como balanceador
hosts: balancer
become: true
vars:
backends_ips: "{{ groups['backends'] | map('extract', hostvars, ['inventory_hostname']) | list }}"
# Si se prefiere, se puede reconstruir la lista desde un registro. Aquí usamos 'groups'.
tasks:
- name: Instalar Nginx
apt:
name: nginx
state: present
update_cache: yes
- name: Configurar Nginx para balanceo de carga
template:
dest: /etc/nginx/sites-available/default
mode: 0644
src: nginx-balanceador.j2
- name: Reiniciar Nginx
service:
name: nginx
state: restarted
# Plantilla Jinja2 nginx-balanceador.j2:
#
# upstream backends {
# server {{ groups['backends'][0] }};
# server {{ groups['backends'][1] }};
# }
# server {
# listen 80;
# location / {
# proxy_pass http://backends;
# }
# }
Explicación y mejoras
- Infraestructura como código: La creación y disposición de recursos cloud están completamente automatizadas[3].
- Balanceo real: El playbook configura Nginx en modo proxy inverso round-robin, distribuyendo la carga entre los Apache de los backends.
-
Escalabilidad: Añade más backends en la variable
backend_count
y modifícalo en la plantilla Nginx para autodescubrimiento inteligente. - Entorno reproducible: El despliegue se puede destruir y repetir fácilmente. Ideal para lab tests, demos o entornos de staging.
Template Jinja2 (nginx-balanceador.j2
)
upstream backends {
{% for ip in groups['backends'] %}
server {{ ip }};
{% endfor %}
}
server {
listen 80;
location / {
proxy_pass http://backends;
}
}
Consejos y troubleshooting
- ¿Permisos SSH? Añade tus claves correctamente y asegúrate de que el grupo de seguridad abre los puertos necesarios.
-
Error de dependencias Ansible: Instala los módulos
amazon.aws
conansible-galaxy collection install amazon.aws
. -
¿No tienes AWS? Puedes adaptar el playbook a cualquier proveedor de nube ajustando los módulos EC2 por los equivalentes de Azure (
azure_rm
) o GCP (gcp_compute
). -
Destrucción de recursos: Añade tareas con estado
absent
para limpiar y evitar gastos innecesarios.
¡Listo para desplegar tu primera infraestructura web escalable en la nube con Ansible! ¿Te animas a llevar tu automatización al siguiente nivel?