Files

3.0 KiB

Hetzner Server Inventory Compilation

When asked to document all Hetzner servers, services, and running applications:

1. Query the Hetzner API for server list

import urllib.request, json
token = open('/root/.hermes/scripts/.hetzner_token').read().strip()
headers = {'Authorization': f'Bearer {token}'}
req = urllib.request.Request('https://api.hetzner.cloud/v1/servers', headers=headers)
data = json.loads(urllib.request.urlopen(req, timeout=10).read())

for s in data.get('servers', []):
    print(f'{s["name"]}{s.get("public_net",{}).get("ipv4",{}).get("ip","?")}{s.get("status")}')

2. Cross-reference with existing documentation

Check these sources in order:

  • /root/.hermes/skills/devops/infrastructure-automation/references/server-inventory-snapshot.md — shows app-to-server mapping
  • /root/.hermes/skills/devops/infrastructure-automation/references/disaster-recovery-plan.md — shows DR architecture
  • Scripts in /root/.hermes/scripts/ — function calls, IP references, API keys (e.g. snapshot-hetzner.py)
  • Memory store (memory tool) and facts_store for past user statements

3. Mark verified vs assumed

Marking Meaning
🟢 Verified Confirmed by SSH or API response
🟡 Assumed From old inventory doc, needs SSH verification
🔴 Unknown No data available

SSH verification: If you can SSH in with the wisp_rsa key, run docker ps, systemctl list-units --type=service --state=running, and hostnamectl status to confirm. If no SSH access exists, document it as a gap.

4. Document the access map

Not every server has the same SSH keys deployed. Track which servers are accessible with which keys:

Server SSH User Key Access
app1 (netcup) root wisp_rsa
app1-bu (Hetzner) root wisp_rsa
ai.itpropartner.com ippadmin ?

5. S3 backup

Upload the finished inventory to s3://hermes-vps-backups/standby/server-inventory.md for DR access.

Pitfalls

  • Hetzner API hostname vs OS hostnameGET /v1/servers/{id} returns the cloud provider's label, which may differ from the OS hostname. Both are valid — note which you're reporting.
  • Missing SSH key for most servers — The wisp_rsa key was only deployed on app1 (netcup) and app1-bu (standby). All other Hetzner boxes need the SSH key injected via rescue mode (see infrastructure-automation skill's Hetzner rescue section) or the user's own key.
  • Old inventory may be stale — apps may have been consolidated between servers since the document was written. Mark "needs SSH verification" rather than stating as fact.
  • The data.get('datacenter',{}) may return empty — The Hetzner API response has a datacenter field with a location sub-object (city, country). Not all API shapes include these. Handle gracefully.
  • Don't fabricate service details — If you can't SSH in to verify what's running, say "from old inventory — needs verification" rather than guessing.