From eebacd248df512e4ec71c3e39996a9f7f3b7b3a0 Mon Sep 17 00:00:00 2001 From: Joachim Hummel Date: Fri, 26 Jun 2026 18:04:46 +0200 Subject: [PATCH] add hetzner-server-available-list flow and document it in README Co-Authored-By: Claude Sonnet 4.6 --- README.md | 35 ++++++++++ hetzner-server-available-list.yaml | 102 +++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 hetzner-server-available-list.yaml diff --git a/README.md b/README.md index d77157e..5621ee7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Aktuell enthalten: * `linux_apt-upgrade.yaml` * `hetzner-vm-provision.yaml` * `hetzner-server-type-location-update.yaml` +* `hetzner-server-available-list.yaml` * `.env.example` Der erste Flow scannt mehrere Docker-Hosts per SSH, sucht nach Docker-Compose-Stacks und schreibt daraus eine Dropdown-Liste in den Kestra KV-Store. @@ -173,6 +174,40 @@ TF_BACKEND_ENDPOINT --- +### `hetzner-server-available-list.yaml` + +Kestra-Flow zum automatischen Abrufen aller laufenden Hetzner Cloud Server. + +**Namespace:** `hetzner` +**Trigger:** Alle 15 Minuten, täglich 07:00–21:00 Uhr (Europe/Berlin) + +Der Flow: + +1. **Hetzner API abfragen** — ruft alle vorhandenen Server ab (Name, Status, IPv4, Server-Typ, Standort, Labels, Erstelldatum) +2. **Servernamen extrahieren** — erzeugt eine separate JSON-Liste mit nur den Namen für Kestra-Dropdowns +3. **MinIO/S3 Upload** — schreibt beide JSON-Dateien ins S3-Backend unter `inventory/` +4. **KV-Store setzen** — speichert die Servernamen unter dem Key `hetzner_server_names` + +Ausgaben: + +| Ziel | Pfad / Key | +|---|---| +| S3 | `inventory/hetzner-server-available.json` (vollständige Serverdaten) | +| S3 | `inventory/hetzner-server-names.json` (nur Namen) | +| KV-Store | `hetzner_server_names` | + +Benötigte Kestra Secrets: + +```text +HCLOUD_TOKEN +AWS_ACCESS_KEY_ID +AWS_SECRET_ACCESS_KEY +TF_BACKEND_BUCKET +TF_BACKEND_ENDPOINT +``` + +--- + ### `.env.example` Beispiel-Datei für benötigte Umgebungsvariablen und Secrets. diff --git a/hetzner-server-available-list.yaml b/hetzner-server-available-list.yaml new file mode 100644 index 0000000..b140bdc --- /dev/null +++ b/hetzner-server-available-list.yaml @@ -0,0 +1,102 @@ +id: hetzner-server-available-list +namespace: hetzner + +triggers: + - id: every-15-minutes-daytime + type: io.kestra.plugin.core.trigger.Schedule + cron: "*/15 7-21 * * *" + timezone: Europe/Berlin + +tasks: + - id: fetch_servers + type: io.kestra.plugin.scripts.shell.Commands + containerImage: alpine:latest + + env: + HCLOUD_TOKEN: "{{ secret('HCLOUD_TOKEN') }}" + + beforeCommands: + - apk add --no-cache curl jq + + commands: + - | + set -eo pipefail + + curl -sS \ + -H "Authorization: Bearer $HCLOUD_TOKEN" \ + "https://api.hetzner.cloud/v1/servers" \ + | jq -c ' + [ + .servers[] + | { + id: .id, + name: .name, + status: .status, + ipv4: .public_net.ipv4.ip, + server_type: .server_type.name, + location: .datacenter.location.name, + labels: .labels, + created: .created + } + ] + ' > hetzner-server-available.json + + jq -c '[.[].name]' hetzner-server-available.json > hetzner-server-names.json + + echo "Komplette Serverliste:" + cat hetzner-server-available.json + + echo "Nur Servernamen für Kestra Dropdown:" + cat hetzner-server-names.json + + outputFiles: + - hetzner-server-available.json + - hetzner-server-names.json + + - id: upload_to_minio + type: io.kestra.plugin.scripts.shell.Commands + containerImage: minio/mc:latest + + env: + AWS_ACCESS_KEY_ID: "{{ secret('AWS_ACCESS_KEY_ID') }}" + AWS_SECRET_ACCESS_KEY: "{{ secret('AWS_SECRET_ACCESS_KEY') }}" + TF_BACKEND_BUCKET: "{{ secret('TF_BACKEND_BUCKET') }}" + TF_BACKEND_ENDPOINT: "{{ secret('TF_BACKEND_ENDPOINT') }}" + + inputFiles: + hetzner-server-available.json: "{{ outputs.fetch_servers.outputFiles['hetzner-server-available.json'] }}" + hetzner-server-names.json: "{{ outputs.fetch_servers.outputFiles['hetzner-server-names.json'] }}" + + commands: + - | + set -eo pipefail + + mc alias set tfstate "$TF_BACKEND_ENDPOINT" "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" + + mc cp hetzner-server-available.json "tfstate/$TF_BACKEND_BUCKET/inventory/hetzner-server-available.json" + mc cp hetzner-server-names.json "tfstate/$TF_BACKEND_BUCKET/inventory/hetzner-server-names.json" + + echo "Dateien wurden nach MinIO geschrieben:" + echo "$TF_BACKEND_BUCKET/inventory/hetzner-server-available.json" + echo "$TF_BACKEND_BUCKET/inventory/hetzner-server-names.json" + + - id: set_server_names_kv + type: io.kestra.plugin.core.kv.Set + key: hetzner_server_names + kvType: JSON + value: "{{ read(outputs.fetch_servers.outputFiles['hetzner-server-names.json']) }}" + + - id: log_result + type: io.kestra.plugin.core.log.Log + message: | + ✅ Hetzner-Serverliste wurde aktualisiert. + + MinIO: + s3://{{ secret('TF_BACKEND_BUCKET') }}/inventory/hetzner-server-available.json + s3://{{ secret('TF_BACKEND_BUCKET') }}/inventory/hetzner-server-names.json + + Kestra KV wurde gesetzt: + hetzner_server_names + + Inhalt: + {{ read(outputs.fetch_servers.outputFiles['hetzner-server-names.json']) }}