Introducción

Cuando la infraestructura crece, agregar hosts manualmente en Zabbix se vuelve insostenible. La solución natural es automatizar el proceso usando Ansible, combinando la instalación del agente en los servidores objetivo con el registro automático del host en Zabbix Server vía su API REST.

En este artículo construiremos un flujo completo de automatización con los siguientes objetivos:

  • Instalar y configurar Zabbix Agent2 en servidores Debian/Ubuntu usando un playbook de Ansible.
  • Registrar automáticamente cada nuevo servidor como host en Zabbix Server utilizando la API REST.
  • Asignar templates según el rol del servidor (web, database, load balancer, etc.).
  • Verificar que la monitorización esté activa y recolectando datos.

Requisitos previos

Necesitamos los siguientes elementos configurados previamente:

  • Un servidor Ansible (control node) con acceso SSH a los servidores objetivo.
  • Zabbix Server 7.x instalado y accesible desde el control node.
  • Un token de API de Zabbix con permisos de administración.
  • Python 3 y la librería requests en el control node para las llamadas a la API.

Paso 1: Estructura del proyecto Ansible

Creamos la estructura de directorios y archivos para nuestro proyecto:

mkdir -p ansible-zabbix/{inventories,playbooks,roles/zabbix-agent/{tasks,templates,vars}}
cd ansible-zabbix

Paso 2: Inventario de Ansible

Definimos los hosts agrupados por rol en el inventario:

# inventories/production.yml
all:
  children:
    webservers:
      hosts:
        web-01:
          ansible_host: 192.168.1.10
        web-02:
          ansible_host: 192.168.1.11
      vars:
        zabbix_host_group: "Web Servers"
        zabbix_template: "Linux by Zabbix agent"

    databases:
      hosts:
        db-01:
          ansible_host: 192.168.1.20
        db-02:
          ansible_host: 192.168.1.21
      vars:
        zabbix_host_group: "Database Servers"
        zabbix_template: "Linux by Zabbix agent"

    loadbalancers:
      hosts:
        lb-01:
          ansible_host: 192.168.1.30
      vars:
        zabbix_host_group: "Load Balancers"
        zabbix_template: "Linux by Zabbix agent"

  vars:
    ansible_user: root
    zabbix_server_host: 192.168.1.1
    zabbix_api_url: "http://192.168.1.1/zabbix/api_jsonrpc.php"
    zabbix_api_token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Paso 3: Playbook para instalar Zabbix Agent

El siguiente playbook instala y configura Zabbix Agent2 en todos los servidores destino:

# playbooks/install-agent.yml
---
- name: Instalar y configurar Zabbix Agent2
  hosts: all
  gather_facts: true
  roles:
    - zabbix-agent

Y el role correspondiente:

# roles/zabbix-agent/tasks/main.yml
---
- name: Agregar repositorio oficial de Zabbix
  apt:
    deb: "https://repo.zabbix.com/zabbix/7.0/debian/pool/main/z/zabbix-release/zabbix-release_7.0-1+debian12_all.deb"
    state: present

- name: Instalar Zabbix Agent2
  apt:
    name: zabbix-agent2
    state: present
    update_cache: yes

- name: Configurar zabbix_agent2.conf
  template:
    src: zabbix_agent2.conf.j2
    dest: /etc/zabbix/zabbix_agent2.conf
    owner: zabbix
    group: zabbix
    mode: '0644'
  notify: restart zabbix-agent2

- name: Iniciar y habilitar zabbix-agent2
  systemd:
    name: zabbix-agent2
    state: started
    enabled: yes

La plantilla del agente:

{# roles/zabbix-agent/templates/zabbix_agent2.conf.j2 #}
Server={{ zabbix_server_host }}
ServerActive={{ zabbix_server_host }}
Hostname={{ inventory_hostname }}
ListenPort=10050
LogFile=/var/log/zabbix/zabbix_agent2.log
LogFileSize=2
DebugLevel=3
Include=/etc/zabbix/zabbix_agent2.d/*.conf

Y los handlers:

# roles/zabbix-agent/handlers/main.yml
---
- name: restart zabbix-agent2
  systemd:
    name: zabbix-agent2
    state: restarted

Paso 4: Playbook para registrar hosts en Zabbix vía API

Este playbook usa un script Python que consume la API REST de Zabbix para crear o actualizar hosts. La autenticación se realiza mediante un token API pre-generado:

# playbooks/register-hosts.yml
---
- name: Registrar hosts en Zabbix Server via API
  hosts: all
  gather_facts: true
  tasks:
    - name: Generar token de autenticación (si no existe)
      set_fact:
        api_token: "{{ zabbix_api_token }}"

    - name: Registrar/actualizar host en Zabbix
      uri:
        url: "{{ zabbix_api_url }}"
        method: POST
        body_format: json
        body:
          jsonrpc: "2.0"
          method: host.create
          params:
            host: "{{ inventory_hostname }}"
            interfaces:
              - type: 1
                main: 1
                useip: 1
                ip: "{{ ansible_default_ipv4.address }}"
                dns: ""
                port: 10050
            groups:
              - groupid: "{{ zabbix_group_id | default(7) }}"
            templates:
              - templateid: "{{ zabbix_template_id | default(10001) }}"
            status: 0
          auth: "{{ api_token }}"
          id: 1
        headers:
          Content-Type: "application/json-rpc"
      register: api_response

    - name: Mostrar resultado de la API
      debug:
        msg: "Host {{ inventory_hostname }} creado con hostid {{ api_response.json.result.hostids[0] }}"

Paso 5: Variables por grupo y verificación

Podemos asignar diferentes plantillas según el rol del servidor usando variables de grupo en el inventario. Por ejemplo, los servidores web podrían usar la plantilla adicional «Apache by Zabbix agent» para monitorizar métricas específicas de Apache/Nginx:

# inventories/production.yml
webservers:
  vars:
    zabbix_host_group: "Web Servers"
    zabbix_templates:
      - name: "Linux by Zabbix agent"
      - name: "Apache by Zabbix agent"
    zabbix_host_macro:
      - macro: "{$APACHE_STATUS_URL}"
        value: "http://localhost/server-status"

Para lanzar todo el despliegue de forma ordenada:

# 1. Instalar el agente en todos los servidores
ansible-playbook -i inventories/production.yml playbooks/install-agent.yml

# 2. Registrar los hosts en Zabbix Server
ansible-playbook -i inventories/production.yml playbooks/register-hosts.yml

# 3. Verificar conectividad desde Zabbix
echo "Listar hosts registrados..."
curl -s -X POST http://192.168.1.1/zabbix/api_jsonrpc.php   -H "Content-Type: application/json-rpc"   -d '{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
      "output": ["hostid", "host", "status"],
      "filter": {"status": 0}
    },
    "auth": "'"$ZABBIX_TOKEN"'",
    "id": 1
  }' | jq '.result[] | {hostid, host, status}'

Verificación final

Después de ejecutar los playbooks, debemos verificar que los hosts aparecen en la interfaz web de Zabbix con estado ZBX verde y que los datos empiezan a fluir:

# Desde el servidor Zabbix, comprobar que los agentes responden
zabbix_get -s 192.168.1.10 -k system.hostname
zabbix_get -s 192.168.1.10 -k system.cpu.load[all,avg1]

# Ver logs del servidor Zabbix
tail -f /var/log/zabbix/zabbix_server.log | grep -E "(resolved|received)"

Si todo está correcto, veremos el hostname del servidor monitorizado y su carga de CPU en tiempo real. En el frontend de Zabbix, el dashboard mostrará los nuevos hosts con datos en Latest Data y los triggers empezarán a evaluarse automáticamente.

Conclusión

Hemos automatizado por completo el ciclo de despliegue de monitorización con Ansible + Zabbix: desde la instalación del agente hasta el registro del host en el servidor central, usando templates y grupos diferenciados por rol. Este flujo permite agregar nuevos servidores a la infraestructura con un solo comando, garantizando que todos queden monitorizados con la configuración correcta desde el primer momento.

Infografía Ansible + Zabbix: Despliegue automatizado de monitorización desde Ansible
Infografía: Ansible + Zabbix: Despliegue automatizado de monitorización desde Ansible