infra/ansible/roles/monitor
Graham McIntire 88bdbbe88f
ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2)
Codifies the bare-metal Icinga2 master + Icinga Web 2 stack on
monitor.vntx.net (Ubuntu 22.04, Apache + mod_php, MariaDB 10.6, Icinga
2.16, IDO-MySQL backend). Re-running the role against the live host
should produce a near-identical configuration.

Role includes:
- Icinga apt repo + full package set (icinga2, ido-mysql, icingaweb2,
  monitoring-plugins, nagios-plugins-contrib, php + apache deps).
- MariaDB DB + user provisioning for both icinga2 (IDO daemon) and
  icingaweb2 (UI), plus a separate read-only `icinga` user that the UI
  uses to read the IDO. Schema bootstrapped only on first install.
- Templated icinga2 config (constants/zones/icinga2.conf), features-
  enabled symlinks (api/checker/command/ido-mysql/mainlog), and the
  three secret-bearing conf.d files (api-users, pagerduty x2) wired to
  vault vars.
- 23 dormant conf.d/* host + service definitions copied verbatim under
  files/. The live install has `include_recursive "conf.d"` commented
  out (a node-setup CLI artifact); role mirrors that. Set
  `icinga2_load_confd: true` in host_vars to rehydrate them.
- Icinga Web 2 ini files (config/auth/groups/roles/modules) + templated
  resources.ini for DB credentials. monitoring module enabled via
  symlink. icingaweb2 admin user bootstrapped on first install via a
  one-shot insert into icingaweb_user (gated on schema-not-yet-imported).
- Apache rewrite + ssl modules. Vhost itself is left to certbot --apache
  (Let's Encrypt cert is operator-managed, role doesn't manage it).

Cluster-wide cleanup:
- Gut roles/general/tasks/debian/icinga2.yml down to the uninstall
  safety net (kept the sweep that removes icinga2 from non-monitoring
  hosts). The previous master-side install + cert-distribution tasks
  referenced templates that never existed in the role; the new monitor
  role replaces them properly.

Operator action before first apply:
- Create host_vars/monitor.vntx.net/vault.yml with the seven required
  secrets (see roles/monitor/README.md). Live values can be pulled from
  /etc/icinga2/conf.d/{api-users,pagerduty-*,ido-mysql}.conf and
  /etc/icingaweb2/resources.ini on the live host.
- Generate the icingaweb2 admin password hash via
  `php -r 'echo password_hash("plaintext", PASSWORD_DEFAULT);'`.
- Run --check --diff before applying; the role is meant to be idempotent
  but hasn't been verified against the live install.
2026-05-08 13:00:53 -05:00
..
defaults ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2) 2026-05-08 13:00:53 -05:00
files ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2) 2026-05-08 13:00:53 -05:00
handlers ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2) 2026-05-08 13:00:53 -05:00
tasks ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2) 2026-05-08 13:00:53 -05:00
templates ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2) 2026-05-08 13:00:53 -05:00
README.md ansible: add 'monitor' role mirroring live monitor.vntx.net (Icinga2 + Web 2) 2026-05-08 13:00:53 -05:00

monitor role

Builds an Icinga2 master + Icinga Web 2 stack matching the live install on monitor.vntx.net:

  • Ubuntu 22.04 + Apache 2.4 + mod_php + MariaDB 10.6 + Icinga 2.16
  • Single zone, master-only (no satellites configured but zones.conf is templated to add them later)
  • IDO-MySQL backend; icinga2 daemon writes status, icinga user read-only-selects for the Web 2 UI, icingaweb2 user owns the UI's own DB
  • 25 dormant conf.d/* host + service files shipped under files/ and copied verbatim. The live install has include_recursive "conf.d" commented out (a node-setup CLI artifact); this role mirrors that. Set icinga2_load_confd: true in host_vars to rehydrate them.

Required vault variables

Encrypt these with ansible-vault (e.g. host_vars/monitor.vntx.net/vault.yml):

# Icinga API users (api-users.conf)
icinga2_api_user_root_password: "..."
icinga2_api_user_icingaweb2_password: "..."

# Icinga2 daemon → IDO database
icinga2_ido_db_password: "..."

# icingaweb2 UI → its own database
icingaweb2_db_password: "..."

# icingaweb2 UI → IDO database (separate read-only user)
icingaweb2_ido_db_password: "..."

# Constants
icinga2_iftraffic_snmp_community: "..."
icinga2_ticket_salt: ""        # only needed for distributed setups

# PagerDuty integration keys
icinga2_pagerduty_key: "..."
icinga2_pagerduty_servers_key: "..."

# icingaweb2 admin user (web UI password). Generate the hash on any host
# with PHP installed:  php -r 'echo password_hash("plaintext", PASSWORD_DEFAULT);'
icingaweb2_admin_password_hash: "$2y$10$..."

What the role does NOT manage

  • Let's Encrypt certificate provisioning. The live install used certbot --apache; this role assumes the cert already exists at /etc/letsencrypt/live/<host>/. Run certbot once by hand.
  • The icingaweb2 schema is imported once on first install. Schema upgrades after Icinga Web 2 minor version bumps are not handled here — see /usr/share/icingaweb2/schema/upgrades/ and run the matching upgrade SQL by hand.
  • Distributed monitoring satellites. The role provisions a single-node master; add Endpoint/Zone objects in zones.d/ (or extend zones.conf.j2) when you wire satellites in.