Programmatic Zabbix template generation — Monitoring as Code
Project description
zbxtemplar
A Pythonic framework for programmatic Zabbix Template generation (Monitoring as Code).
The goal is to cover the essential Zabbix configuration primitives — not every possible option. If you need a field that isn't exposed, raw dicts and string expressions give you an escape hatch.
Installation
pip install .
Core Architecture
The project follows the src-layout:
zbxtemplar.entities— Domain models: Template, Host, Item, Trigger, Graph, Dashboard.zbxtemplar.core— Module contract (TemplarModule), loader, serialization, shared types.zbxtemplar.main— CLI entry point.
Module Contract
Templates and hosts are defined as Python classes that inherit from TemplarModule.
The constructor is the contract — all configuration logic lives in __init__.
from zbxtemplar.core import TemplarModule
from zbxtemplar.entities import Template, Item, Host, TriggerPriority
from zbxtemplar.entities.Template import TemplateGroup
from zbxtemplar.entities.Host import HostGroup, AgentInterface
class MyModule(TemplarModule):
def __init__(self):
super().__init__()
template = Template(name="My Service", groups=[TemplateGroup("Custom Templates")])
template.add_tag("Service", "MyApp")
template.add_macro("THRESHOLD", 90, "Alert threshold")
item = Item("CPU Usage", "system.cpu.util", template.name)
item.add_trigger("High CPU", "last", ">",
template.get_macro("THRESHOLD"),
priority=TriggerPriority.HIGH)
template.add_item(item)
host = Host("My Server", groups=[HostGroup("Linux Servers")])
host.add_template(template)
host.add_interface(AgentInterface(ip="192.168.1.10"))
self.templates = [template]
self.hosts = [host]
A module file can contain multiple TemplarModule subclasses.
The loader discovers all of them by class name.
Running standalone
Add a __main__ guard to run the module directly:
if __name__ == "__main__":
import yaml
module = MyModule()
print(yaml.dump(module.to_export(), default_flow_style=False, sort_keys=False))
CLI
# Combined output (templates + hosts)
zbxtemplar module.py output.yml
# Separate outputs
zbxtemplar module.py --templates-output templates.yml --hosts-output hosts.yml
# Combined + separate
zbxtemplar module.py output.yml --templates-output templates.yml --hosts-output hosts.yml
# With UUID namespace
zbxtemplar module.py output.yml --namespace "My Company"
| Argument | Description |
|---|---|
module |
Path to a .py file with TemplarModule subclass(es) |
output |
Combined output YAML file path (optional if split outputs are given) |
--templates-output |
Output YAML file path for templates only |
--hosts-output |
Output YAML file path for hosts only |
--namespace |
UUID namespace for deterministic ID generation |
Programmatic Loading
from zbxtemplar.core import load_module
modules = load_module("path/to/module.py")
# Returns {"ClassName": <instance>, ...}
for name, mod in modules.items():
export = mod.to_export() # Full zabbix_export dict
Entities Reference
Template
template = Template(name="My Template", groups=[TemplateGroup("Custom Group")])
template.add_tag("Service", "MyApp")
template.add_macro("TIMEOUT", 30, "Connection timeout")
template.add_item(item)
Host
from zbxtemplar.entities import Host
from zbxtemplar.entities.Host import HostGroup, AgentInterface
host = Host("My Host", groups=[HostGroup("Linux Servers")])
host.add_tag("Environment", "Production")
host.add_macro("HOST_PORT", 8080, "Application port")
# Link a template
host.add_template(template)
# Add an interface (first interface becomes the default)
iface = AgentInterface(ip="192.168.1.10", port="10050")
host.add_interface(iface)
# Host-level items, triggers, graphs work the same as on templates
item = Item("Host Uptime", "system.uptime", host.name)
item.set_interface(iface)
host.add_item(item)
# Macro lookup walks linked templates when not found on the host
host.get_macro("TEMPLATE_MACRO") # falls back to template macros
Hosts produce UUID-free YAML (matching Zabbix export format). Dashboards are template-only and cannot be added to hosts.
AgentInterface is the built-in interface type (type: ZABBIX). Custom interface types can be created by subclassing HostInterface.
HostGroup
from zbxtemplar.entities.Host import HostGroup
group = HostGroup("Linux Servers")
Works the same as TemplateGroup — name-based identity with a deterministic UUID.
Item
item = Item("CPU Usage", "system.cpu.util")
# Expression helper — builds Zabbix function strings
item.expr("last") # last(/host/key)
item.expr("min", "10m") # min(/host/key,10m)
item.expr("count", "#10") # count(/host/key,#10)
# Single-item trigger shorthand
item.add_trigger("High CPU", "last", ">", 90,
priority=TriggerPriority.HIGH,
description="CPU threshold exceeded")
# With function args
item.add_trigger("Sustained high", "min", ">", 100,
fn_args=("10m",), priority=TriggerPriority.WARNING)
All enum values (ItemType, ValueType, TriggerPriority, GraphType, DrawType, CalcFnc, etc.) follow the Zabbix export format documentation.
Trigger
# Standalone (multi-item) trigger — raw expression string
Trigger(name="Complex alert",
expression=item1.expr("last") + ">0 and " + item2.expr("min", "5m") + "<100",
priority=TriggerPriority.WARNING,
description="Multi-item condition")
Macro
Macros work seamlessly in string contexts:
template.add_macro("MY_MACRO", 1, "Description")
macro = template.get_macro("MY_MACRO")
str(macro) # {$MY_MACRO}
item.expr("last") + ">" + macro # last(/host/key)>{$MY_MACRO}
item.add_trigger("Alert", "last", ">", macro) # works as threshold
Graph
graph = Graph("CPU Graph",
graph_type=GraphType.STACKED,
y_min_type=YAxisType.FIXED, y_min=0,
y_max_type=YAxisType.FIXED, y_max=100)
graph.add_item(item1, "FF0000")
graph.add_item(item2, "00FF00",
drawtype=DrawType.BOLD_LINE,
calc_fnc=CalcFnc.MAX,
yaxisside=YAxisSide.RIGHT)
Dashboard
from zbxtemplar.entities import Dashboard, DashboardPage
from zbxtemplar.entities.DashboardWidget import ClassicGraph
page = DashboardPage(name="Overview", display_period=120)
page.add_widget(ClassicGraph(template=template.name, graph=graph, width=36, height=5))
dashboard = Dashboard("My Dashboard", display_period=60, auto_start=YesNo.NO)
dashboard.add_page(page)
template.add_dashboard(dashboard)
Widgets are concrete subclasses of Widget (abstract). Each widget type lives in zbxtemplar.entities.DashboardWidget. Creating custom widgets is straightforward — subclass Widget, define type and widget_fields().
Global Configuration
from zbxtemplar.core.ZbxEntity import set_uuid_namespace
set_uuid_namespace("My Company") # Deterministic UUIDs scoped to namespace
Executor
The executor is a separate tool that applies generated YAML and other configuration to a live Zabbix instance. Install with the executor extra:
pip install ".[executor]"
Commands
# Bootstrap or rotate super admin password
zbxtemplar-exec set_super_admin --new-password $ZBX_ADMIN_PASSWORD \
--user Admin --password zabbix --url http://localhost
# Set global macros
zbxtemplar-exec set_macro SNMP_COMMUNITY public --token $ZBX_TOKEN
zbxtemplar-exec set_macro macros.yml --token $ZBX_TOKEN
# Import Zabbix-native YAML (templates, hosts, media types, etc.)
zbxtemplar-exec apply zabbix-native.yml --token $ZBX_TOKEN
# Apply state configuration (user groups, users)
zbxtemplar-exec decree state.yml --token $ZBX_TOKEN
# Create service accounts (shorthand — feeds into decree)
zbxtemplar-exec add_user users.yml --token $ZBX_TOKEN
Connection credentials can be passed via CLI flags (--url, --token, --user, --password) or environment variables (ZABBIX_URL, ZABBIX_TOKEN, ZABBIX_USER, ZABBIX_PASSWORD).
Decree
A decree is zbxtemplar's declarative YAML format for live-state configuration that has no Zabbix-native import format. A single decree file can contain any combination of supported sections, processed in dependency order.
user_group:
- name: Templar Users
gui_access: INTERNAL
host_groups:
- name: Linux servers
permission: READ
template_groups:
- name: Custom Templates
permission: READ_WRITE
add_user:
- username: zbx-service
role: Super admin role
password: ${ZBX_SERVICE_PASSWORD}
groups:
- Templar Users
All references are by name — the executor resolves IDs at runtime. In a scroll, decree accepts a file path, an inline dict, or a list mixing both.
Named constants for gui_access: DEFAULT, INTERNAL, LDAP, DISABLED.
Named constants for permission: NONE, READ, READ_WRITE.
Severity uses comma-separated names instead of bitmasks: NOT_CLASSIFIED, INFORMATION, WARNING, AVERAGE, HIGH, DISASTER.
If a user has token defined and the token already exists, the executor raises an error. Set force_token: true to delete and recreate the token.
The add_user CLI command is a shorthand that feeds a file containing add_user: into the decree pipeline.
Scroll
A scroll is a static YAML file describing a full deployment sequence. Stages execute in a fixed pipeline order: bootstrap → templates → state.
stages:
- stage: bootstrap
set_super_admin:
password: ${ZBX_ADMIN_PASSWORD}
set_macro:
- name: SNMP_COMMUNITY
value: public
- name: DB_PASSWORD
value: ${DB_PASSWORD}
type: secret
- stage: templates
apply:
- templates.yml
- media-types.yml
- stage: state
decree:
user_group:
- name: Templar Users
gui_access: INTERNAL
add_user:
- username: zbx-service
role: Super admin role
password: ${ZBX_SERVICE_PASSWORD}
zbxtemplar-exec scroll deploy.scroll.yml --token $ZBX_TOKEN
zbxtemplar-exec scroll deploy.scroll.yml --from-stage state
zbxtemplar-exec scroll deploy.scroll.yml --only-stage bootstrap
File paths in scroll actions resolve relative to the scroll file's directory, not the working directory. String values may contain ${ENV_VAR} references, resolved from the OS environment before any API calls. Missing variables cause a pre-flight failure — no partial execution.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zbxtemplar-0.5.0.tar.gz.
File metadata
- Download URL: zbxtemplar-0.5.0.tar.gz
- Upload date:
- Size: 30.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f18b3cb03a6039ac3bfb6c22fd4935c0a221680ad3b67cbbe25b16872a0adc38
|
|
| MD5 |
27a7c59106b4cf8fc4d89c99a2e750c8
|
|
| BLAKE2b-256 |
92e0636b98c329bbf60d77b316f3442884b83f3231d963a1b73f0f98532bc3ea
|
File details
Details for the file zbxtemplar-0.5.0-py3-none-any.whl.
File metadata
- Download URL: zbxtemplar-0.5.0-py3-none-any.whl
- Upload date:
- Size: 28.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
288d58c19e1d2a783849e9cb5b02ce89694d238cf86292705fc21857e2dbe28a
|
|
| MD5 |
41088193a46667b021dd2a42919b8630
|
|
| BLAKE2b-256 |
c892ae8c46377759def2185c76f61dd78aed76aa7285219e26a6009a6a7d4777
|