Architecture — LastVet Slack enrichment¶
Placement¶
Runs on the observability VM (192.168.1.93, MagicDNS observability.tailc3bbdc.ts.net), colocated with Alertmanager, Prometheus, Loki, and Grafana.
Data flow¶
Prometheus / Loki ruler
↓
Alertmanager (:9093)
↓ HTTP POST (localhost)
lastvet-slack-enrichment (:8088)
↓ read-only queries
Prometheus / Loki / Grafana (127.0.0.1)
↓ incoming webhook
Slack #alerts-lastvet
Critical alerts still send email directly from Alertmanager (unchanged).
Listeners¶
| Bind | Port | Routes | Consumers |
|---|---|---|---|
127.0.0.1 |
8088 | POST /webhook/alertmanager |
Alertmanager (same host) |
| Tailscale IP | 8089 | GET /health |
UptimeRobot, operators |
Prometheus and Loki queries use loopback (127.0.0.1). Slack button links use Tailnet MagicDNS (observability.tailc3bbdc.ts.net) so they open in the operator browser, not localhost on the operator machine.
Webhook requests from non-localhost addresses receive 403.
Enrichment pipeline¶
- Parse Alertmanager grouped payload (
status, labels, annotations, timestamps). - Load per-alert rules from
config/enrichment-rules.yaml. - Build Grafana Explore link (alert start −30m → start +10m).
- Resolve runbook URL from annotation or lookup table.
- Query Loki for last 5 log lines (optional).
- Query Prometheus for instant metric snapshot (optional).
- Render Slack Block Kit with action buttons: Open Grafana, Runbook, Silence 1h.
Partial enrichment failures append a context note; basic alert still posts if the whole pipeline fails.
Security¶
- No auto-remediation; read-only observability queries.
- Slack webhook URL stored in
/etc/lastvet-slack-enrichment/enrichment.env(BWS restore, mode 640). - Webhook not exposed off localhost.