- Python 55.9%
- Jinja 40.2%
- JavaScript 3.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Information problems are listed as context only. The sweep does not comment on or acknowledge them, and the runbook says the same. |
||
| .woodpecker | ||
| defaults | ||
| files | ||
| handlers | ||
| meta | ||
| roles | ||
| tasks | ||
| templates | ||
| .ansible-lint | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .markdownlint-cli2.jsonc | ||
| .yamllint | ||
| AGENTS.md | ||
| ansible.cfg | ||
| playbook.yaml | ||
| readme.md | ||
| renovate.json | ||
Ansible Role: claptrap
claptrap is the first responder for Zabbix problems. Zabbix sends a problem to a small receiver on oc01, which starts
a claude -p run (Claude Code with Haiku) with a runbook. claptrap investigates the host over ssh, applies a fix
only if it is on the allowlist, and posts a summary as a comment on the problem. If the problem is still open after
10 minutes, Zabbix escalates to the admin anyway.
Requirements
| Operating System | Version |
|---|---|
| Debian | 13 and newer |
- The
claptrapuser, its ssh key andclaptrap-ctlon every host come from thecommonrole. - ssh reaches the hosts through the bastion (
ProxyJump), so no firewall changes on the hosts are needed. - oc01 must allow TCP 8484 from zabbix01 (
firewall_host_rulesin the inventory).
The shield
| Layer | Where | What |
|---|---|---|
| claude tools | oc01 | --tools Bash plus only the proxmox mcp server, settings from a root-owned --settings file (dontAsk, bypass disabled) |
| guard hook | oc01 | PreToolUse hook on every call: only the proxmox tools and claptrap-ssh <host> '<command>' with the command fully single-quoted, so nothing runs or expands on oc01 |
| claptrap-ssh | oc01 | only hosts in claptrap_ssh_domains, never oc01 itself, fixed root-owned ssh config |
| unprivileged user | hosts | reading works without sudo; secrets readable only by root stay unreadable |
| sudoers | hosts | claptrap may only run /usr/local/sbin/claptrap-ctl |
| claptrap-ctl | hosts | validates every argument: services, journal, /tmp cleanup, docker, guarded reboot |
| suggestions | hosts | claptrap-ctl suggest only logs to syslog (tag claptrap-suggest), nothing is executed |
| proxmox token | Proxmox | claptrap@pve!oc01: VM.Audit, VM.PowerMgmt, VM.Snapshot, VM.GuestAgent.Audit on /vms, only VM.Audit + VM.Snapshot on protected guests, PVEAuditor on / |
| mcp-proxmox claptrap profile | oc01 | only read tools plus guarded vm_start, vm_reboot, vm_reset, snapshot_list, snapshot_cleanup; every write in /var/log/claptrap/pve-audit.log |
Every claptrap-ctl call is logged to syslog with tag claptrap-ctl, refused calls contain DENIED.
claude logs in with your Claude Code subscription (claude setup-token, valid for a year), so its runs count
against that seat's usage limits. When the limit is hit, the run fails, the comment says so and the 10 minute
escalation still pages the admin.
Variables
| Variable | Required | Default | Description |
|---|---|---|---|
| claptrap_claude_version | No | "2.1.306" |
Claude Code release (tracked by renovate) |
| claptrap_model | No | "haiku" |
model used by claude |
| claptrap_port | No | 8484 |
receiver port |
| claptrap_max_runs | No | 2 |
parallel claude runs |
| claptrap_run_timeout | No | 480 |
seconds per run, below the 10 minute page |
| claptrap_zabbix_url | No | monitoring api_jsonrpc.php |
Zabbix API url for comments |
| claptrap_bastion | No | "bastion.simoncor.net" |
ssh jump host |
| claptrap_ssh_domains | No | siempie and hackerboys | hosts claptrap may reach |
| vault_claptrap_receiver_secret | Yes | shared secret with the Zabbix webhook | |
| vault_claptrap_zabbix_token | Yes | API token of the Zabbix user claptrap |
|
| vault_claptrap_ssh_private_key | Yes | private key of the claptrap user |
|
| claptrap_mcp_proxmox_version | No | "1.2.0" |
mcp-proxmox release (renovate) |
| claptrap_pve_protected | No | never-reboot list | guests without power actions |
| claptrap_pve_snapshot_max_age | No | "24h" |
snapshots older than this are deleted |
| claptrap_pve_snapshot_max_count | No | 6 |
keep at most this many (autosnaps last) |
| vault_claptrap_pve_token_secret | Yes | secret of claptrap@pve!oc01 |
|
| vault_claptrap_claude_token | Yes | output of claude setup-token |
|
| claptrap_claude_token_expires | Yes | "" |
token expiry, YYYY-MM-DD (1 year) |
| claptrap_claude_token_warn_days | No | 30 |
days of renewal reminders in comments |
Zabbix setup
-
User role
claptrap: type User, no UI elements, API access enabled with the method allow listevent.acknowledge, and of the problem actions only Add problem comments. claptrap can never acknowledge, close, suppress or change the severity of a problem. -
User group
claptrap: frontend access disabled, Read permission on the host groups claptrap handles. -
User
claptrapin that group with that role, and an API token (vault_claptrap_zabbix_token). -
Media type
claptrap: type Webhook, scriptfiles/zabbix-webhook.js, parameters as listed at the top of the script. Add message templates for both Problem and Problem recovery (the script ignores recoveries, but Zabbix fails the alert without a template). Give theclaptrapuser this media (send to:oc01). -
Trigger action
claptrap firstfor severities Warning and Average:- step 1, immediately: send to user
claptrapvia media typeclaptrap - step 2, after 10 minutes: send to the admin via Telegram
The escalation stops when the problem resolves, so a successful fix never pages the admin.
- step 1, immediately: send to user
-
Trigger action for High and Disaster (
Alert Simon): step 1 sends to the admin via Telegram and, in parallel, to userclaptrap. The admin is paged right away; claptrap's findings follow as a comment.
Tags
| Tags | Purpose |
|---|---|
| claptrap_install | claude, receiver, guard, claptrap-ssh, systemd |
| claptrap_config | secrets, runbook, claude, mcp and ssh config |
Usage
Run playbook.yaml through Semaphore, limited to oc01.siempie.internal. Logs: journalctl -u claptrap for the
receiver, /var/log/claptrap/<eventid>.log for each run.