Ansible Zabbix — Deploy and Configure Monitoring
Introduction
Zabbix is an enterprise-class monitoring solution for networks, servers, and applications. With the community.zabbix Ansible collection, you can automate the entire monitoring stack — deploy Zabbix server, install agents on all hosts, configure monitoring templates, and manage alerts through code.
Prerequisites
ansible-galaxy collection install community.zabbix
pip install zabbix-api
Deploy Zabbix Server
---
- name: Deploy Zabbix Server
hosts: monitoring
become: true
vars:
zabbix_version: "7.0"
zabbix_db_password: "{{ vault_zabbix_db_password }}"
zabbix_server_ip: "{{ ansible_default_ipv4.address }}"
tasks:
- name: Install Zabbix repository
ansible.builtin.apt:
deb: "https://repo.zabbix.com/zabbix/{{ zabbix_version }}/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_{{ ansible_distribution_release }}_all.deb"
when: ansible_os_family == "Debian"
- name: Install Zabbix server packages
ansible.builtin.apt:
name:
- zabbix-server-pgsql
- zabbix-frontend-php
- zabbix-nginx-conf
- zabbix-sql-scripts
- zabbix-agent2
- postgresql
- python3-psycopg2
state: present
update_cache: true
- name: Create Zabbix database
community.postgresql.postgresql_db:
name: zabbix
encoding: UTF-8
become_user: postgres
- name: Create Zabbix database user
community.postgresql.postgresql_user:
name: zabbix
password: "{{ zabbix_db_password }}"
db: zabbix
priv: ALL
become_user: postgres
- name: Import Zabbix schema
ansible.builtin.shell:
cmd: zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | psql -U zabbix zabbix
become_user: postgres
args:
creates: /etc/zabbix/.schema_imported
- name: Mark schema as imported
ansible.builtin.file:
path: /etc/zabbix/.schema_imported
state: touch
mode: '0644'
- name: Configure Zabbix server
ansible.builtin.lineinfile:
path: /etc/zabbix/zabbix_server.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
loop:
- { regexp: '^# DBPassword=', line: 'DBPassword={{ zabbix_db_password }}' }
- { regexp: '^# CacheSize=', line: 'CacheSize=128M' }
- { regexp: '^# StartPollers=', line: 'StartPollers=10' }
notify: Restart Zabbix server
- name: Configure Nginx for Zabbix
ansible.builtin.lineinfile:
path: /etc/zabbix/nginx.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
loop:
- { regexp: '#.*listen.*8080', line: ' listen 80;' }
- { regexp: '#.*server_name', line: ' server_name zabbix.example.com;' }
notify: Restart Nginx
- name: Start services
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
loop:
- zabbix-server
- zabbix-agent2
- nginx
- php8.3-fpm
handlers:
- name: Restart Zabbix server
ansible.builtin.systemd:
name: zabbix-server
state: restarted
- name: Restart Nginx
ansible.builtin.systemd:
name: nginx
state: restarted
Deploy Zabbix Agent on All Hosts
---
- name: Deploy Zabbix Agent
hosts: all
become: true
vars:
zabbix_server_ip: "192.168.1.10"
zabbix_version: "7.0"
tasks:
- name: Install Zabbix agent2
ansible.builtin.package:
name: zabbix-agent2
state: present
- name: Configure Zabbix agent
ansible.builtin.template:
src: zabbix_agent2.conf.j2
dest: /etc/zabbix/zabbix_agent2.conf
mode: '0644'
notify: Restart Zabbix agent
- name: Start Zabbix agent
ansible.builtin.systemd:
name: zabbix-agent2
state: started
enabled: true
handlers:
- name: Restart Zabbix agent
ansible.builtin.systemd:
name: zabbix-agent2
state: restarted
# templates/zabbix_agent2.conf.j2
Server={{ zabbix_server_ip }}
ServerActive={{ zabbix_server_ip }}
Hostname={{ inventory_hostname }}
LogFile=/var/log/zabbix/zabbix_agent2.log
LogFileSize=10
PidFile=/var/run/zabbix/zabbix_agent2.pid
Include=/etc/zabbix/zabbix_agent2.d/*.conf
ControlSocket=/tmp/agent.sock
Register Hosts via API
---
- name: Register hosts in Zabbix
hosts: localhost
connection: local
vars:
zabbix_url: "http://zabbix.example.com"
zabbix_user: Admin
zabbix_password: "{{ vault_zabbix_admin_password }}"
tasks:
- name: Create host group
community.zabbix.zabbix_group:
server_url: "{{ zabbix_url }}"
login_user: "{{ zabbix_user }}"
login_password: "{{ zabbix_password }}"
host_groups:
- Production Servers
- Web Servers
state: present
- name: Register hosts
community.zabbix.zabbix_host:
server_url: "{{ zabbix_url }}"
login_user: "{{ zabbix_user }}"
login_password: "{{ zabbix_password }}"
host_name: "{{ item }}"
host_groups:
- Production Servers
link_templates:
- Linux by Zabbix agent active
interfaces:
- type: agent
main: 1
dns: "{{ item }}"
status: enabled
state: present
loop: "{{ groups['all'] }}"
Custom Monitoring Items
- name: Create custom monitoring template
community.zabbix.zabbix_template:
server_url: "{{ zabbix_url }}"
login_user: "{{ zabbix_user }}"
login_password: "{{ zabbix_password }}"
template_name: "Custom App Monitoring"
template_groups:
- Templates
state: present
- name: Deploy custom UserParameters
ansible.builtin.copy:
content: |
# Custom application monitoring
UserParameter=app.status,systemctl is-active myapp
UserParameter=app.connections,ss -tn | grep :8080 | wc -l
UserParameter=app.response_time,curl -s -o /dev/null -w '%{time_total}' http://localhost:8080/health
UserParameter=disk.iops[*],iostat -d $1 1 2 | tail -1 | awk '{print $$4}'
dest: /etc/zabbix/zabbix_agent2.d/custom.conf
mode: '0644'
notify: Restart Zabbix agent
Troubleshooting
| Issue | Solution |
|---|---|
| Agent not connecting | Check firewall port 10050/10051 |
| No data in Zabbix | Verify Server= matches Zabbix server IP |
| API authentication failed | Check admin credentials, URL must include /api_jsonrpc.php path |
| Template import failed | Ensure template XML version matches Zabbix version |
| High CPU on server | Increase CacheSize, tune StartPollers |
Best Practices
- Use Zabbix Agent 2 (Go-based) — better performance than legacy agent
- Active checks (
ServerActive) — agent pushes data, works behind NAT - Template everything — link templates to hosts, don't configure items per host
- Autoregister agents — configure auto-registration rules for dynamic environments
- Encrypt agent communication — use PSK or TLS certificates
- Monitor the monitor — set up external checks for Zabbix server itself
Conclusion
Ansible automates the entire Zabbix lifecycle — from server deployment to agent installation to host registration via API. The community.zabbix collection handles the API integration, while standard Ansible modules manage packages, configs, and services. Define your monitoring as code alongside your infrastructure.