Despliegue automático de una infraestructura web con balanceador Nginx y alta disponibilidad en la nube con Ansible

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 con ansible-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?

Avatar

Por Mid