Integrate Zabbix 7 with network automation and orchestration tools using Ansible and Python APIs

Advanced 45 min Apr 14, 2026 22 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Build comprehensive network automation workflows by integrating Zabbix 7 monitoring with Ansible playbooks and custom Python scripts. This tutorial covers API authentication, automated host provisioning, and dynamic monitoring configuration for enterprise infrastructure management.

Prerequisites

  • Zabbix 7 server with admin access
  • Python 3.8+
  • Ansible 2.9+
  • Network connectivity to target hosts
  • Basic understanding of YAML and Python

What this solves

Modern network infrastructure requires seamless integration between monitoring and automation tools to maintain scalability and reliability. This tutorial demonstrates how to integrate Zabbix 7 with Ansible and Python APIs to create automated workflows for host provisioning, template deployment, and dynamic configuration management. You'll build a complete automation pipeline that reduces manual monitoring setup and enables infrastructure-as-code practices.

Step-by-step configuration

Install Python dependencies and Ansible modules

Start by installing the required Python libraries and Ansible collections for Zabbix integration. These packages provide the API client libraries and Ansible modules needed for automation.

sudo apt update
sudo apt install -y python3-pip python3-venv ansible
pip3 install --user pyzabbix requests
ansible-galaxy collection install community.zabbix
ansible-galaxy collection install ansible.posix
sudo dnf update -y
sudo dnf install -y python3-pip python3-virtualenv ansible
pip3 install --user pyzabbix requests
ansible-galaxy collection install community.zabbix
ansible-galaxy collection install ansible.posix

Configure Zabbix API authentication

Create a dedicated API user in Zabbix with appropriate permissions for automation tasks. This user will authenticate API requests from Ansible and Python scripts.

mkdir -p ~/zabbix-automation/{playbooks,scripts,inventory}
cd ~/zabbix-automation

Create the API authentication configuration file with your Zabbix server details:

zabbix:
  server: https://zabbix.example.com
  username: api-automation
  password: secure-api-password-2024
  validate_certs: true
  timeout: 30

default_templates:
  - Template Module ICMP Ping
  - Template OS Linux by Zabbix agent
  
default_groups:
  - Linux servers
  - Production
  
proxy_settings:
  use_proxy: false
  proxy_name: ""
  
notification_settings:
  enable_alerts: true
  email_recipient: admin@example.com

Create Ansible inventory configuration

Set up dynamic inventory sources and group variables for consistent host management across your infrastructure.

[zabbix_servers]
zabbix-primary ansible_host=203.0.113.10 zabbix_role=primary
zabbix-secondary ansible_host=203.0.113.11 zabbix_role=secondary

[monitoring_targets]
web-server-01 ansible_host=203.0.113.20 server_type=web environment=production
db-server-01 ansible_host=203.0.113.21 server_type=database environment=production
app-server-01 ansible_host=203.0.113.22 server_type=application environment=staging

[monitoring_targets:vars]
zabbix_agent_version=6.4
zabbix_server_host=203.0.113.10
zabbix_agent_hostname_type=fqdn

Configure group variables for different server types:

zabbix_api_server: "{{ hostvars['zabbix-primary']['ansible_host'] }}"
zabbix_api_user: api-automation
zabbix_api_password: secure-api-password-2024

monitoring_templates:
  web:
    - Template App HTTP Service
    - Template OS Linux by Zabbix agent
    - Template Module ICMP Ping
  database:
    - Template DB MySQL
    - Template OS Linux by Zabbix agent
    - Template Module ICMP Ping
  application:
    - Template App Generic Java JMX
    - Template OS Linux by Zabbix agent
    - Template Module ICMP Ping

host_groups_mapping:
  production: "Production servers"
  staging: "Staging servers"
  development: "Development servers"

Build Ansible playbook for host provisioning

Create a comprehensive playbook that automates Zabbix host creation, template assignment, and monitoring configuration based on inventory metadata.

---
  • name: Provision Zabbix monitoring for infrastructure hosts
hosts: monitoring_targets gather_facts: yes vars_files: - ../config.yml tasks: - name: Create host groups if they don't exist community.zabbix.zabbix_group: server_url: "{{ zabbix.server }}" login_user: "{{ zabbix.username }}" login_password: "{{ zabbix.password }}" validate_certs: "{{ zabbix.validate_certs }}" group_name: "{{ host_groups_mapping[environment] }}" state: present delegate_to: localhost run_once: true - name: Create Zabbix host entry community.zabbix.zabbix_host: server_url: "{{ zabbix.server }}" login_user: "{{ zabbix.username }}" login_password: "{{ zabbix.password }}" validate_certs: "{{ zabbix.validate_certs }}" host_name: "{{ inventory_hostname }}" visible_name: "{{ inventory_hostname }} ({{ server_type | title }})" description: "{{ server_type | title }} server in {{ environment }} environment" host_groups: - "{{ host_groups_mapping[environment] }}" link_templates: "{{ monitoring_templates[server_type] }}" interfaces: - type: agent main: 1 useip: 1 ip: "{{ ansible_host }}" port: 10050 - type: snmp main: 1 useip: 1 ip: "{{ ansible_host }}" port: 161 details: version: 2 community: public inventory: tag: "{{ environment }}" location: "{{ datacenter | default('Primary DC') }}" contact: "{{ owner_email | default('admin@example.com') }}" state: present delegate_to: localhost - name: Configure host macros based on server type community.zabbix.zabbix_hostmacro: server_url: "{{ zabbix.server }}" login_user: "{{ zabbix.username }}" login_password: "{{ zabbix.password }}" validate_certs: "{{ zabbix.validate_certs }}" host_name: "{{ inventory_hostname }}" macro_name: "{{ item.key }}" macro_value: "{{ item.value }}" state: present loop: - { key: '{$ENVIRONMENT}', value: "{{ environment }}" } - { key: '{$SERVER_TYPE}', value: "{{ server_type }}" } - { key: '{$CONTACT_EMAIL}', value: "{{ owner_email | default('admin@example.com') }}" } delegate_to: localhost

Create Python automation script for advanced operations

Develop a Python script that performs complex Zabbix operations not easily handled by Ansible, including bulk operations and custom metric handling.

#!/usr/bin/env python3

import json
import yaml
import argparse
from pyzabbix import ZabbixAPI
from datetime import datetime, timedelta
import logging
import sys
from typing import Dict, List, Optional

Configure logging

logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('/var/log/zabbix-automation.log'), logging.StreamHandler(sys.stdout) ] ) logger = logging.getLogger(__name__) class ZabbixAutomation: def __init__(self, config_file: str): with open(config_file, 'r') as f: self.config = yaml.safe_load(f) self.zapi = ZabbixAPI(self.config['zabbix']['server']) self.zapi.login( self.config['zabbix']['username'], self.config['zabbix']['password'] ) logger.info(f"Connected to Zabbix API version {self.zapi.api_version()}") def bulk_host_operations(self, action: str, host_pattern: str) -> Dict: """Perform bulk operations on hosts matching pattern""" hosts = self.zapi.host.get( search={'host': host_pattern}, searchWildcardsEnabled=True, output=['hostid', 'host', 'status'] ) results = {'success': [], 'failed': []} for host in hosts: try: if action == 'enable': self.zapi.host.update( hostid=host['hostid'], status=0 ) elif action == 'disable': self.zapi.host.update( hostid=host['hostid'], status=1 ) elif action == 'maintenance': self._create_maintenance(host) results['success'].append(host['host']) logger.info(f"Successfully {action}d host {host['host']}") except Exception as e: results['failed'].append({ 'host': host['host'], 'error': str(e) }) logger.error(f"Failed to {action} host {host['host']}: {e}") return results def create_custom_dashboard(self, dashboard_name: str, host_group: str) -> str: """Create custom dashboard for host group""" try: # Get hosts from group hosts = self.zapi.host.get( groupids=self.zapi.hostgroup.get( filter={'name': host_group} )[0]['groupid'], output=['hostid', 'host'] ) # Dashboard configuration dashboard_config = { 'name': dashboard_name, 'display_period': 30, 'auto_start': 1, 'pages': [{ 'name': 'Overview', 'display_period': 0, 'widgets': [] }] } # Add widgets for each host widget_id = 0 for i, host in enumerate(hosts[:10]): # Limit to 10 hosts x = (i % 2) * 12 y = (i // 2) * 6 dashboard_config['pages'][0]['widgets'].append({ 'type': 'graph', 'name': f"{host['host']} - CPU Usage", 'x': x, 'y': y, 'width': 12, 'height': 6, 'fields': [ {'type': 0, 'name': 'source_type', 'value': '0'}, {'type': 4, 'name': 'itemid', 'value': str(self._get_cpu_item_id(host['hostid']))} ] }) widget_id += 1 # Create dashboard result = self.zapi.dashboard.create(dashboard_config) logger.info(f"Created dashboard '{dashboard_name}' with ID {result['dashboardids'][0]}") return result['dashboardids'][0] except Exception as e: logger.error(f"Failed to create dashboard: {e}") raise def _get_cpu_item_id(self, hostid: str) -> Optional[str]: """Get CPU utilization item ID for host""" items = self.zapi.item.get( hostids=hostid, search={'key_': 'system.cpu.util'}, output=['itemid'] ) return items[0]['itemid'] if items else None def _create_maintenance(self, host: Dict) -> None: """Create maintenance period for host""" maintenance_data = { 'name': f"Maintenance - {host['host']}", 'active_since': int(datetime.now().timestamp()), 'active_till': int((datetime.now() + timedelta(hours=2)).timestamp()), 'hostids': [host['hostid']], 'timeperiods': [{ 'timeperiod_type': 0, 'start_date': int(datetime.now().timestamp()), 'period': 7200 # 2 hours }] } self.zapi.maintenance.create(maintenance_data) def export_configuration(self, output_file: str, export_type: str = 'hosts') -> None: """Export Zabbix configuration to file""" try: if export_type == 'hosts': data = self.zapi.host.get( output='extend', selectGroups='extend', selectTemplates='extend', selectMacros='extend' ) elif export_type == 'templates': data = self.zapi.template.get( output='extend', selectGroups='extend', selectItems='extend' ) with open(output_file, 'w') as f: json.dump(data, f, indent=2, default=str) logger.info(f"Exported {export_type} configuration to {output_file}") except Exception as e: logger.error(f"Failed to export configuration: {e}") raise def main(): parser = argparse.ArgumentParser(description='Zabbix Automation Tool') parser.add_argument('--config', default='config.yml', help='Config file path') parser.add_argument('--action', required=True, choices=['bulk-enable', 'bulk-disable', 'bulk-maintenance', 'create-dashboard', 'export'], help='Action to perform') parser.add_argument('--pattern', help='Host pattern for bulk operations') parser.add_argument('--dashboard-name', help='Dashboard name') parser.add_argument('--host-group', help='Host group name') parser.add_argument('--export-type', choices=['hosts', 'templates'], default='hosts') parser.add_argument('--output-file', default='zabbix-export.json', help='Export output file') args = parser.parse_args() try: automation = ZabbixAutomation(args.config) if args.action.startswith('bulk-'): action = args.action.replace('bulk-', '') if not args.pattern: raise ValueError("Pattern required for bulk operations") results = automation.bulk_host_operations(action, args.pattern) print(json.dumps(results, indent=2)) elif args.action == 'create-dashboard': if not args.dashboard_name or not args.host_group: raise ValueError("Dashboard name and host group required") dashboard_id = automation.create_custom_dashboard(args.dashboard_name, args.host_group) print(f"Created dashboard with ID: {dashboard_id}") elif args.action == 'export': automation.export_configuration(args.output_file, args.export_type) print(f"Configuration exported to {args.output_file}") except Exception as e: logger.error(f"Automation failed: {e}") sys.exit(1) if __name__ == '__main__': main()

Make the script executable and create the log directory:

chmod +x ~/zabbix-automation/scripts/zabbix_automation.py
sudo mkdir -p /var/log
sudo touch /var/log/zabbix-automation.log
sudo chown $USER:$USER /var/log/zabbix-automation.log

Integrate with Ansible AWX for orchestration

Configure Ansible AWX integration for centralized automation management. This setup assumes you have AWX installed and running.

---
  • name: AWX Integration for Zabbix Automation
hosts: localhost vars: awx_host: https://awx.example.com awx_username: admin awx_password: awx-admin-password organization_name: Infrastructure Team project_name: Zabbix Automation inventory_name: Production Infrastructure tasks: - name: Create AWX project for Zabbix automation uri: url: "{{ awx_host }}/api/v2/projects/" method: POST user: "{{ awx_username }}" password: "{{ awx_password }}" force_basic_auth: yes validate_certs: yes body_format: json body: name: "{{ project_name }}" organization: 1 scm_type: git scm_url: https://github.com/company/zabbix-automation.git scm_branch: main scm_update_on_launch: true status_code: [201, 400] register: project_creation - name: Create job template for host provisioning uri: url: "{{ awx_host }}/api/v2/job_templates/" method: POST user: "{{ awx_username }}" password: "{{ awx_password }}" force_basic_auth: yes validate_certs: yes body_format: json body: name: "Provision Zabbix Monitoring" description: "Automated Zabbix host provisioning" job_type: run inventory: 2 project: "{{ project_creation.json.id | default(1) }}" playbook: "playbooks/provision-monitoring.yml" credential: 1 verbosity: 1 ask_variables_on_launch: true status_code: [201, 400] register: job_template - name: Create workflow template for complete automation uri: url: "{{ awx_host }}/api/v2/workflow_job_templates/" method: POST user: "{{ awx_username }}" password: "{{ awx_password }}" force_basic_auth: yes validate_certs: yes body_format: json body: name: "Complete Zabbix Infrastructure Setup" description: "End-to-end Zabbix monitoring deployment" organization: 1 survey_enabled: true extra_vars: environment: production enable_notifications: true status_code: [201, 400]

Create automation wrapper scripts

Build convenient wrapper scripts that combine Ansible playbooks with Python automation for common workflows.

#!/bin/bash

Zabbix Monitoring Deployment Script

set -euo pipefail BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" CONFIG_FILE="${BASE_DIR}/config.yml" LOG_FILE="/var/log/zabbix-automation.log"

Colors for output

RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log() { echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } log_success() { log "${GREEN}✓ $1${NC}" } log_warning() { log "${YELLOW}⚠ $1${NC}" } log_error() { log "${RED}✗ $1${NC}" } usage() { cat << EOF Usage: $0 [OPTIONS] Options: -e, --environment ENV Target environment (production, staging, development) -t, --target HOST_PATTERN Host pattern to target (default: all) -a, --action ACTION Action to perform (deploy, update, remove) -d, --dashboard NAME Create dashboard with specified name -g, --group GROUP Target host group -v, --verbose Enable verbose output -h, --help Show this help message Examples: $0 -e production -a deploy $0 -e staging -t "web-*" -a update $0 -d "Production Overview" -g "Production servers" EOF } check_prerequisites() { log "Checking prerequisites..." local missing_deps=() command -v ansible >/dev/null 2>&1 || missing_deps+=("ansible") command -v python3 >/dev/null 2>&1 || missing_deps+=("python3") python3 -c "import pyzabbix" >/dev/null 2>&1 || missing_deps+=("python3-pyzabbix") if [[ ${#missing_deps[@]} -gt 0 ]]; then log_error "Missing dependencies: ${missing_deps[*]}" exit 1 fi if [[ ! -f "$CONFIG_FILE" ]]; then log_error "Config file not found: $CONFIG_FILE" exit 1 fi log_success "All prerequisites satisfied" } deploy_monitoring() { local environment="$1" local target_pattern="${2:-all}" log "Deploying Zabbix monitoring for environment: $environment" # Run Ansible playbook if ansible-playbook \ -i "${BASE_DIR}/inventory/hosts.yml" \ "${BASE_DIR}/playbooks/provision-monitoring.yml" \ --limit="$target_pattern" \ --extra-vars="environment=$environment" \ ${VERBOSE:+--verbose}; then log_success "Ansible playbook completed successfully" else log_error "Ansible playbook failed" return 1 fi # Post-deployment validation log "Running post-deployment validation..." python3 "${BASE_DIR}/scripts/zabbix_automation.py" \ --config="$CONFIG_FILE" \ --action=export \ --export-type=hosts \ --output-file="${BASE_DIR}/validation-export-$(date +%Y%m%d-%H%M%S).json" log_success "Deployment completed successfully" } create_dashboard() { local dashboard_name="$1" local host_group="$2" log "Creating dashboard: $dashboard_name for group: $host_group" if python3 "${BASE_DIR}/scripts/zabbix_automation.py" \ --config="$CONFIG_FILE" \ --action=create-dashboard \ --dashboard-name="$dashboard_name" \ --host-group="$host_group"; then log_success "Dashboard created successfully" else log_error "Dashboard creation failed" return 1 fi }

Parse command line arguments

ENVIRONMENT="" TARGET="all" ACTION="deploy" DASHBOARD_NAME="" HOST_GROUP="" VERBOSE="" while [[ $# -gt 0 ]]; do case $1 in -e|--environment) ENVIRONMENT="$2" shift 2 ;; -t|--target) TARGET="$2" shift 2 ;; -a|--action) ACTION="$2" shift 2 ;; -d|--dashboard) DASHBOARD_NAME="$2" shift 2 ;; -g|--group) HOST_GROUP="$2" shift 2 ;; -v|--verbose) VERBOSE="1" shift ;; -h|--help) usage exit 0 ;; *) log_error "Unknown option: $1" usage exit 1 ;; esac done

Main execution

log "Starting Zabbix automation deployment" check_prerequisites case "$ACTION" in deploy|update) if [[ -z "$ENVIRONMENT" ]]; then log_error "Environment is required for deploy/update actions" exit 1 fi deploy_monitoring "$ENVIRONMENT" "$TARGET" ;; dashboard) if [[ -z "$DASHBOARD_NAME" || -z "$HOST_GROUP" ]]; then log_error "Dashboard name and host group are required" exit 1 fi create_dashboard "$DASHBOARD_NAME" "$HOST_GROUP" ;; *) log_error "Unknown action: $ACTION" exit 1 ;; esac log_success "Zabbix automation completed successfully"

Make the deployment script executable:

chmod +x ~/zabbix-automation/scripts/deploy-monitoring.sh

Set up automated maintenance workflows

Create scheduled automation for maintenance windows and bulk operations using systemd timers.

[Unit]
Description=Zabbix Automated Maintenance
After=network.target

[Service]
Type=oneshot
User=zabbix-automation
Group=zabbix-automation
WorkingDirectory=/home/zabbix-automation/zabbix-automation
Environment=HOME=/home/zabbix-automation
ExecStart=/home/zabbix-automation/zabbix-automation/scripts/zabbix_automation.py --config=config.yml --action=bulk-maintenance --pattern="staging-*"
StandardOutput=append:/var/log/zabbix-automation.log
StandardError=append:/var/log/zabbix-automation.log
[Unit]
Description=Weekly Zabbix Maintenance Window
Requires=zabbix-maintenance.service

[Timer]
OnCalendar=Sun 02:00
Persistent=true

[Install]
WantedBy=timers.target

Enable and start the maintenance timer:

sudo systemctl daemon-reload
sudo systemctl enable zabbix-maintenance.timer
sudo systemctl start zabbix-maintenance.timer
sudo systemctl status zabbix-maintenance.timer

Verify your setup

Test the automation pipeline and verify all components are working correctly.

# Test Ansible connectivity to Zabbix API
ansible localhost -m community.zabbix.zabbix_host_info \
  -a "server_url=https://zabbix.example.com login_user=api-automation login_password=secure-api-password-2024 host_name=test-host"

Run the deployment script in dry-run mode

~/zabbix-automation/scripts/deploy-monitoring.sh -e staging -a deploy -v

Test Python automation script

python3 ~/zabbix-automation/scripts/zabbix_automation.py \ --config ~/zabbix-automation/config.yml \ --action export \ --export-type hosts \ --output-file test-export.json

Verify systemd timer status

sudo systemctl list-timers zabbix-maintenance.timer

Check automation logs

tail -f /var/log/zabbix-automation.log
Note: The integration provides comprehensive logging through both Ansible verbose output and Python logging. Monitor /var/log/zabbix-automation.log for detailed execution information and troubleshooting.

Common issues

SymptomCauseFix
API authentication fails Incorrect credentials or insufficient permissions Verify API user has Admin role in Zabbix, check config.yml credentials
Ansible playbook hangs on host creation Network connectivity or Zabbix server overload Increase timeout in config, check zabbix.timeout setting
Python script fails with import error Missing pyzabbix package Reinstall with pip3 install --user pyzabbix requests
Host templates not applied Template names don't match Zabbix exactly Check template names in Zabbix UI, update monitoring_templates in vars
AWX integration returns 401 errors Incorrect AWX credentials or expired session Verify AWX admin credentials, check AWX user permissions
Systemd timer doesn't execute Service file permissions or user context Check service status with systemctl status zabbix-maintenance.service
Dashboard creation fails silently Host group doesn't exist or no hosts in group Verify host group exists and contains hosts before dashboard creation
Security consideration: Store API credentials securely using Ansible Vault or external secret management systems. Avoid hardcoding passwords in configuration files for production deployments.

Next steps

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.