🟢 Статус: Conceptually stable · v0.1
Концепция устойчива, проверена опытом, литературой и практикой.
08. GitOps для Zabbix — честный взгляд¶
Глава о том, почему нет идеального GitOps для Zabbix, какой реальный спектр подходов используется в рабочей среде, и что выбирать под вашу зрелость и риск-аппетит.
Это дополнение к главе 7 — там описывается, что в фазе 2 нужно завести конфигурацию в Git. Здесь — как именно.
Честный ответ: нет идеального GitOps для Zabbix¶
Это известная боль в сообществе. Zabbix хранит всю конфигурацию в БД, не в файлах. Нет git clone && apply как в Terraform или Kubernetes. Это архитектурное решение авторов, и оно создаёт проблему воспроизводимости.
Процесс «экспорт → Git → импорт руками» — это честный минимум, не эталон. Сакрального смысла в нём нет. Типичные проблемы:
- Кто-то зашёл в UI и поменял триггер → в Git это не попало
- Кто-то сделал импорт не из Git, а из своей локальной копии → расхождение
- Git показывает «последний экспорт», а не «текущее состояние Zabbix»
- Уверенности что они совпадают — никакой, если нет автоматики
Как это решается по-нормальному¶
Спектр от «чуть лучше ручного» до «настоящий IaC».
Уровень 1: Скриптованный экспорт + drift detection¶
Минимум автоматизации — задача по расписанию, которая регулярно экспортирует конфигурацию и коммитит её в Git. Тогда Git это не «то что мы положили», а «слепок реального состояния».
#!/bin/bash
# zabbix_export_to_git.sh — запускается по cron раз в час
ZABBIX_URL="https://zabbix.plant.local/api_jsonrpc.php"
TOKEN=$(cat /etc/zabbix/api_token)
REPO=/opt/zabbix-config
# Экспорт всех шаблонов через API
python3 export_all_templates.py \
--url "$ZABBIX_URL" \
--token "$TOKEN" \
--output "$REPO/templates/"
# Экспорт host groups, hosts, media types...
# ...
cd $REPO
git add -A
git diff --cached --quiet || git commit -m "auto-export $(date +%Y-%m-%dT%H:%M)"
git push
Что это даёт: Git становится аудит-логом реального состояния. Если кто-то руками поменял триггер в UI — через час это появится в Git как коммит с diff. Это уже видно.
Что это не даёт: запрета на прямые изменения в UI. Дисциплина — организационная, не техническая.
⚠️ Без нормализации scheduled auto-export превращает Git в шум. Экспортированный YAML может содержать runtime-поля, изменяющиеся при каждом запросе (lastaccess, triggerid ordering и т.д.). Рекомендации: сортировать поля, убирать нестабильные runtime-значения, один объект — один файл со стабильным именем, использовать
git diff --statдля фильтрации незначительных изменений.
Уровень 2: Ansible community.zabbix¶
Это де-факто стандарт, если нужен IaC для Zabbix.
https://github.com/ansible-collections/community.zabbix
Модули: zabbix_host, zabbix_template, zabbix_hostgroup, zabbix_action, zabbix_user и т.д.
Как выглядит:
# playbook: zabbix_hosts.yml
- name: Ensure 1C app servers in Zabbix
hosts: localhost
tasks:
- name: Add 1C app server
community.zabbix.zabbix_host:
server_url: https://zabbix.plant.local
login_user: admin
login_password: "{{ vault_zabbix_pass }}"
host_name: srv-1c-prod-01
visible_name: "1C App Server 01"
host_groups:
- Applications/1C
link_templates:
- Plant: Linux base
- Plant: 1C App Server
interfaces:
- type: 1 # agent
main: 1
ip: 10.10.20.15
port: 10050
tags:
- tag: env
value: prod
- tag: service
value: 1c-erp
- tag: criticality
value: P1
state: present
Что это даёт: - YAML в Git = желаемое состояние - Idempotent: можно гонять сколько угодно - CI/CD pipeline: merge request → ansible apply → Zabbix обновился
⚠️ Поведение «только diff, не перезаписывает» зависит от конкретного модуля и его параметров. Перед применением в рабочей среде: читайте документацию модуля, запускайте
--check(пробный запуск), пилотируйте на нескольких хостах, проверяйте что теги/шаблоны не удаляются деструктивно при неполном плейбуке.
Где трение:
- Не все объекты Zabbix покрыты модулями одинаково хорошо (шаблоны — хуже всего)
- Шаблоны всё равно проще хранить в YAML и делать zabbix_template модулем для импорта
- Хосты, группы, права, медиа — через Ansible отлично
Уровень 3: Terraform provider¶
Существует: https://github.com/claranet/terraform-provider-zabbix
resource "zabbix_host" "srv_1c_prod_01" {
host = "srv-1c-prod-01"
name = "1C App Server 01"
groups = [zabbix_hostgroup.apps_1c.id]
templates = [
zabbix_template.linux_base.id,
zabbix_template.app_1c.id,
]
agent {
ip = "10.10.20.15"
port = 10050
main = true
}
tags = {
env = "prod"
service = "1c-erp"
criticality = "P1"
}
}
Что это даёт: ближе к полноценному IaC. State в terraform.tfstate, terraform plan как diff перед apply.
Проблемы:
- Provider написан сообществом, не официальный Zabbix
- Поддерживается неравномерно, не все объекты покрыты
- terraform.tfstate надо хранить удалённо (S3/Consul), это инфраструктура
- Если кто-то меняет в UI — state расходится с реальностью, нужен terraform refresh
Итог: интересно для новых инсталляций, для реорганизации легаси — боль.
Уровень 4: Zabbix CLI + CI/CD (ближайший к «настоящему GitOps»)¶
zabbix-cli (https://github.com/unioslo/zabbix-cli) умеет export/import через API в пакетном режиме.
В связке с GitLab CI:
# .gitlab-ci.yml
stages:
- validate
- apply
validate:
script:
- python3 scripts/validate_templates.py templates/
apply:
script:
- zabbix-cli --config zabbix-cli.conf
template import --file templates/plant-linux-base.yaml
template import --file templates/plant-1c-app.yaml
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual # ← ручное подтверждение, не автоприменение
Что даёт: merge request = code review изменения шаблона. Apply по нажатию кнопки в GitLab. Лог кто и когда применил.
Что покрывает export/import — и что не покрывает¶
configuration.export / configuration.import покрывают шаблоны, хосты, группы, карты, экраны, медиа-типы. Это полезный слепок, но не полный снимок Zabbix:
- Пользователи и роли — через
user.get/usergroup.get, отдельно - Actions и escalation rules — через
action.get, не входят в configuration.export - Authentication settings (LDAP, SAML, MFA) — только через UI или отдельные API
- Global macros — через
usermacro.getсglobalmacro=true - Media и уведомления — отчасти в export, но credentials/tokens — нет (см. secret handling ниже)
Для контролируемого применения используй configuration.importcompare — API-метод, возвращающий diff между файлом и текущим состоянием без применения. Это аналог terraform plan для Zabbix-конфигурации.
Как убедиться что Git = Zabbix (drift detection)¶
Это отдельная задача, и без неё любой из подходов выше — «на доверии».
Простой вариант: ежечасный скрипт сравнивает хеши экспортированных YAML с тем, что в Git:
# Псевдокод
exported = zabbix_api.export_all_templates()
committed = git_repo.read_latest("templates/")
diff = diff_yaml(exported, committed)
if diff:
send_alert("Zabbix config drift detected!", diff)
Что это даёт: если кто-то поменял в UI напрямую — через час приходит алерт. Менеджер видит. Это организационный контроль через мониторинг.
Кстати: для контроля UI-изменений в реальном времени надёжнее периодически опрашивать auditlog.get через внешний скрипт и слать события в канал. Zabbix action на EVENT.SOURCE=5 (internal event) технически возможен, но audit-события не всегда маппятся на действия достаточно надёжно — проверяйте поведение на вашей версии.
Что реально делают в промышленной среде¶
Честная картина по зрелости:
| Уровень зрелости | Как управляют конфигом |
|---|---|
| Большинство | Только UI, никакого Git, «в голове и по памяти» |
| Средний уровень | Ручной экспорт в Git «когда вспоминают», как задокументированные снапшоты |
| Хороший уровень | Scheduled auto-export + Ansible для хостов, шаблоны в YAML в Git |
| Зрелые команды | Terraform/Ansible + CI/CD pipeline + drift detection |
| Единицы | Полный IaC, никаких изменений через UI в промышленной среде |
С вероятностью 95%, ваш свечной заводик сейчас на уровне «только UI». Реалистичная цель за год — «хороший уровень».
Что выбрать для завода в рамках проекта¶
Честная рекомендация с учётом ресурсов и сроков:
Фаза 2 (сейчас): - Auto-export в Git по cron (1 вечер работы, даёт аудит-лог) - Ansible для управления хостами (теги, группы, шаблоны) — это решает главную боль массовых изменений - Шаблоны — YAML в Git, импорт через UI или скрипт при изменениях
Фаза 3 / Год 2: - CI/CD pipeline на GitLab (если GitLab уже есть или появится) - Drift detection alert - Постепенно — всё через Ansible, ничего напрямую в UI
Почему не Terraform сейчас: provider сырой для легаси-инсталляций, риски выше пользы. Ansible более зрелый для этой задачи.
Управление секретами — что не кладут в Git¶
Ни в каком из уровней GitOps следующее не хранится в открытом Git-репозитории без шифрования:
| Что | Где хранить |
|---|---|
| API token Zabbix | Ansible Vault / CI/CD variables / Vault |
| Пароли media types (email relay, webhook) | Ansible Vault / CI secrets |
| PSK-ключи агентов | Отдельное хранилище секретов, не в YAML конфиге |
| SNMP community strings | Ansible Vault / Vault |
| Пароли LDAP/SAML binding | Только через Vault или CI environment variables |
| Webhook credentials (Telegram token, etc.) | CI secrets или Ansible Vault |
Инструменты: Ansible Vault, SOPS, HashiCorp Vault, переменные окружения CI. Регулярно ротируйте токены, особенно API token с правом write.
Аварийное изменение через UI¶
Даже при зрелом GitOps бывают ситуации когда нужно немедленно поменять порог, отключить триггер, изменить шаблон — прямо в UI, без pipeline.
Политика аварийных изменений:
- Кто может: только назначенный владелец мониторинга (или дежурный инженер с явным разрешением)
- Что фиксируется: причина в комментарии/тикете (инцидент, номер, что меняется)
- Как потом: в течение следующего рабочего дня — экспорт изменения в Git, коммит со ссылкой на инцидент
- Контроль: drift detection (см. выше) покажет расхождение. Без коммита в Git после аварийного изменения — это техдолг, который надо закрыть
Без явной политики аварийных изменений команда будет тайно менять UI и «забывать» фиксировать изменения в Git, что разрушает весь GitOps.
Коротко¶
Ручной процесс «экспорт → Git → импорт» — это честный минимум который даёт хоть что-то. Гарантии равенства Git и Zabbix без автоматики — действительно нет. Правильный путь: auto-export для аудита + Ansible для изменений + drift detection для контроля. Terraform — хорош для новых инсталляций, не для реорганизации легаси.
Связь с остальными главами¶
- Глава 7 — Roadmap: GitOps вводится в фазе 2 (стандартизация)
- Глава 12 — Эксплуатационная модель мониторинга: часть процессов изменений (окна обслуживания, ввод хостов в мониторинг) удобнее автоматизировать через тот же CI/CD pipeline