- Jinja 100%
Confirmed against the unit's own web UI (OCR'd Info/Variables page): Output Power showed 47.1kW, matching the raw SNMP line-1 value directly (not raw/10). The previous scale: 0.1 fix was wrong — the "0.1W" unit noted in the vendor doc doesn't apply here because this field isn't actually per-line data at all. It's a system-wide total written into the line-1 slot only; lines 2/3 are always 0 because they're unused, not a second/third phase. Same pattern confirmed for upsOutputPercentLoad (Load 39% on the web UI matched raw line 1). Dashboard updated to match: Mitsubishi's output power/load now render as a single accurate "Total" line instead of line 1 mislabeled as "L1" alongside two fake flat-zero "L2"/"L3" series. Liebert is unaffected — its per-line data is genuinely real, confirmed separately, and its "Out Total" sum still applies only to it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| dashboards | ||
| group_vars | ||
| roles/snmp_exporter | ||
| ansible.cfg | ||
| inventory.ini | ||
| README.md | ||
| site.yml | ||
snmp_exporter for the CARC PLG stack (vortex)
Deploys prom/snmp-exporter on vortex.alliance.unm.edu as a rootful
Podman Quadlet unit, polling the Mitsubishi UPS at 129.24.240.37 over
SNMPv2c using the standard UPS-MIB (RFC 1628), and wires a scrape job into
the existing /etc/monitoring/prometheus/prometheus.yml.
Layout
ansible.cfg # inventory path, become prompts for sudo password
inventory.ini # [monitoring] group -> vortex
site.yml # entry-point playbook
group_vars/monitoring.yml # non-secret vars (UPS IP, vendor)
roles/snmp_exporter/
defaults/main.yml # image version, ports, paths — check/bump snmp_exporter_version
tasks/main.yml # deploy config, Quadlet unit, enable service, patch prometheus.yml
handlers/main.yml # restart snmp_exporter / restart prometheus container
templates/
snmp.yml.j2 # hand-written UPS-MIB module (not generator-produced)
snmp_exporter.container.j2 # Podman Quadlet unit
prometheus_snmp_job.yml.j2 # scrape job block inserted into prometheus.yml
What it does
- Writes
/etc/monitoring/snmp_exporter/snmp.yml(mode 0640, root-only — it contains the community string). - Writes
/etc/containers/systemd/snmp_exporter.container(Quadlet unit),daemon-reloads, enables + startssnmp_exporter.service.- Runs with
Network=host, so it listens on the host's:9116directly — no podman network coupling with the other containers needed.
- Runs with
- Inserts a marked, idempotent block into
prometheus.yml'sscrape_configs:(viablockinfile, safe to re-run) targetingvortex.alliance.unm.edu:9116withmodule: [ups]. - Runs
promtool check configinside the runningprometheuscontainer before reloading — if the config is invalid, the play aborts and does not restart Prometheus. - Restarts the
prometheuscontainer (podman restart prometheus) to pick up the new job.
Before you run it
- Bump the pin.
roles/snmp_exporter/defaults/main.ymlpinssnmp_exporter_version: v0.27.0. Check https://github.com/prometheus/snmp_exporter/releases and update if a newer release exists. - Verify the promtool path.
prometheus_container_config_pathin defaults assumes theprometheuscontainer mounts its config at the image's default/etc/prometheus/prometheus.yml. Confirm withsudo podman inspect prometheus | grep -A2 Mountsand adjust the var (via-eorgroup_vars/monitoring.yml) if it differs. - Firewall. Since snmp_exporter uses host networking, if
firewalldis active on vortex and theprometheuscontainer reaches the host over an interface other than loopback, you may need to allow tcp/9116 from the podman bridge subnet. Not handled by this playbook — checksudo firewall-cmd --list-allfirst. - You need the UPS's actual SNMPv2c community string. It is deliberately not stored anywhere in this repo.
Running it
External SSH to vortex is blocked, so this runs locally on the box
itself (ansible_connection=local in inventory.ini) rather than from
an external control machine. Get the repo onto vortex (e.g. git clone
or scp -r from wherever you have campus-network/console access), then
from a shell on vortex:
ansible-playbook site.yml -e snmp_ups_community='<the real community string>'
You'll be prompted for the local sudo (become) password
(become_ask_pass = True in ansible.cfg).
If snmp_ups_community is omitted, the snmp.yml template fails fast
with a clear error instead of writing a broken/empty community string.
Verifying
Run these directly on vortex:
sudo systemctl status snmp_exporter.service
curl -s http://localhost:9116/snmp?target=129.24.240.37\&module=ups | grep ^ups | head -30
sudo podman logs prometheus --tail 50
# in a browser: http://vortex.alliance.unm.edu (via nginx) -> Prometheus -> Status -> Targets -> snmp_ups
Extending later (switches, PDUs)
- Add a new
modules:entry tosnmp.yml.j2(e.g.if_mibfor IF-MIB-based switches, or a vendor MIB for PDUs/environmental sensors). - Add a matching
job_nameblock to a new template (or extendprometheus_snmp_job.yml.j2) with the rightmodule:param and target list. - Since v0.23.0, snmp_exporter splits auth out of the module: define a
new named profile under the top-level
auths:map (e.g.snmpv3_switch) withversion: 3,username,security_level,auth_protocol,password,priv_protocol,priv_password— pull those from new-eextra-vars the same waysnmp_ups_communityis handled now, don't hardcode them — and reference it viaparams: { auth: [snmpv3_switch] }in that module's scrape job (seepublic_v2inprometheus_snmp_job.yml.j2for the pattern). See https://github.com/prometheus/snmp_exporter/blob/main/auth-split-migration.md for background.