Installation¶
There are three ways to run the sync:
- Docker: the quickest option, no Python environment needed
- Python package: install from PyPI and run it as a command, or import it into your own code
- From source: clone the repository and run the script
Every option needs the environment variables for the NetBox and Zabbix connection. Before the first run, prepare NetBox as described in Preparation.
Each run performs one sync and then exits. To keep Zabbix up to date, run it on a schedule, for example from cron:
*/15 * * * * docker run --rm --env-file /etc/netbox-zabbix-sync.env ghcr.io/thenetworkguy/netbox-zabbix-sync:latest
Docker¶
Images are published to the GitHub container registry with the following tags:
| Tag | Contents |
|---|---|
latest |
The latest release |
4.1, 4.1.0, ... |
A specific release |
main |
The current state of the main branch |
Pass the environment variables with -e, or put them in an env file:
docker run --name netbox-zabbix-sync \
-e NETBOX_HOST='https://netbox.local' \
-e NETBOX_TOKEN='secrettoken' \
-e ZABBIX_HOST='https://zabbix.local' \
-e ZABBIX_TOKEN='othersecrettoken' \
ghcr.io/thenetworkguy/netbox-zabbix-sync:latest
This runs one sync with verbose logging. Check the output with docker logs netbox-zabbix-sync.
Configuration file¶
The image contains a copy of config.py.example as its configuration. To use your own configuration, mount it over /opt/netbox-zabbix/config.py:
Settings can also be passed as NBZX_ environment variables.
Command-line flags¶
The image runs python /opt/netbox-zabbix/netbox_zabbix_sync.py -v. To pass other flags, repeat the script path after the image name:
docker run --rm ... ghcr.io/thenetworkguy/netbox-zabbix-sync:latest \
/opt/netbox-zabbix/netbox_zabbix_sync.py -v --sync-vms
Python package¶
The project is published on PyPI as netbox-zabbix-sync and requires Python 3.12 or later.
Command-line tool¶
The package installs a netbox-zabbix-sync command, which accepts the same flags as the script:
Without --config, the command looks for config.py in the current working directory.
Use it in your own code¶
You can also import the Sync class and start a sync from your own scripts:
from netbox_zabbix_sync import Sync
# Only pass the settings you want to change. Everything else uses the defaults.
config = {"clustering": True, "sync_vms": True}
sync = Sync(config)
connected = sync.connect(
nb_host="https://netbox.internal",
nb_token="supersecrettoken",
zbx_host="https://zabbix.internal",
zbx_token="othersecrettoken",
# Or use zbx_user="NetboxSync", zbx_pass="supersecretpassword" instead of a token.
)
if connected:
sync.start()
sync.logout()
Things to know when using the class directly:
- The
configdictionary is merged with the defaults only.config.py,NBZX_environment variables and command-line flags are not read. connect()returnsFalseand logs the reason when it cannot connect. It does not raise an exception.start()takes optionaldevice_filterandvm_filterdictionaries. These are combined withnb_device_filterandnb_vm_filterfrom the config, and override them where keys overlap. For example,sync.start(device_filter={"site": "hq-ams"})syncs only the devices in one site.- The class logs to the
NetBox-Zabbix-synclogger but does not configure any handlers. Set up logging yourself, for example withlogging.basicConfig(level=logging.INFO), or pass your own logger withSync(config, logger=my_logger).
Installation from source¶
Clone the repository:
Install the dependencies with uv:
Or with pip in a virtual environment:
Create your configuration from the example and adjust it as needed (see Configuration):
Then, with the environment variables set, run the script:
# When installed with uv
uv run netbox_zabbix_sync.py -v
# When installed with pip, from the activated virtual environment
python3 netbox_zabbix_sync.py -v
Environment variables¶
The connection details are always read from environment variables, regardless of how you run the script.
| Variable | Required | Description |
|---|---|---|
NETBOX_HOST |
Yes | URL of NetBox, for example https://netbox.local |
NETBOX_TOKEN |
Yes | NetBox API token. Both v1 tokens and v2 tokens (nbt_<key>.<token>, NetBox 4.5 and later) are supported |
ZABBIX_HOST |
Yes | URL of Zabbix, for example https://zabbix.local |
ZABBIX_TOKEN |
One of the two | Zabbix API token |
ZABBIX_USER and ZABBIX_PASS |
One of the two | Zabbix username and password. Only used when ZABBIX_TOKEN is not set |
REQUESTS_CA_BUNDLE |
No | Path to a CA bundle, for NetBox or Zabbix servers that use certificates from a private CA. Used for both connections |
export NETBOX_HOST="https://netbox.local"
export NETBOX_TOKEN="secrettoken"
export ZABBIX_HOST="https://zabbix.local"
export ZABBIX_TOKEN="othersecrettoken"
Settings from config.py can also be set through environment variables with the NBZX_ prefix. See Configuration.
Command-line flags¶
| Flag | Description |
|---|---|
-v, --verbose |
Log informational messages, such as every change made in Zabbix |
-vv, --debug |
Log debug messages of the sync |
-vvv, --debug-all |
Log debug messages of the sync and all libraries it uses |
-q, --quiet |
Only log errors |
-c FILE, --config FILE |
Path to the config file. Default: config.py next to the script, or in the current directory |
--version |
Show the version and exit |
-h, --help |
Show all flags and exit |
Without any of the verbosity flags, only warnings and errors are logged.
Configuration overrides¶
Most settings can also be set on the command line. A flag takes priority over config.py and environment variables.
Boolean settings have an enable and a disable flag, named after the setting with underscores replaced by dashes. For example, --sync-vms enables and --no-sync-vms disables sync_vms. This works for:
clustering, create_hostgroups, create_journal, sync_vms, full_proxy_sync, templates_config_context, templates_config_context_overrule, traverse_regions, traverse_site_groups, extended_site_properties, extended_virtual_chassis, extended_ips, prefer_dns, inventory_sync, oob_sync, usermacro_sync, tag_sync, tag_lower, render_config_context, log_rotation, log_console
Text settings take a value, for example --hostgroup-format "site/role". This works for:
template_cf, device_cf, hostgroup_format, vm_hostgroup_format, inventory_mode, tag_name, tag_value, preferred_ip, log_file
--no-log-file disables logging to a file.
Settings that take a list or a dictionary, such as filters and maps, can only be set in config.py. usermacro_sync = "full" cannot be set with a flag either: use config.py or NBZX_USERMACRO_SYNC=full.