ansible/README.md
2026-03-30 15:19:20 +02:00

371 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ansible Playbooks
Ansible-Setup für Proxmox-VMs, Hetzner-Server und Borg Backup auf Hetzner Storagebox.
## Quickstart
```bash
# Wrapper-Script nutzen
./pfannkuchen.sh setup emby_sascha # VM komplett einrichten
./pfannkuchen.sh backup # Borg auf allen Backup-Hosts
./pfannkuchen.sh update # Alle Hosts updaten
./pfannkuchen.sh gpu tdarr # NVIDIA Setup
./pfannkuchen.sh pve # Proxmox Post-Install
./pfannkuchen.sh passthrough # GPU Passthrough vorbereiten
./pfannkuchen.sh telegraf # Telegraf Monitoring
./pfannkuchen.sh hysteria2 node1 # Hysteria2 + WireGuard
./pfannkuchen.sh ping # Alle Hosts anpingen
./pfannkuchen.sh list # Inventory anzeigen
# Oder direkt mit Ansible
ansible-playbook site.yml -l emby_sascha
ansible-playbook borg-backup.yml -l proxmox
ansible-playbook update.yml
```
## Infrastruktur
### Proxmox Hosts
| Host | IP | GPU |
|-------|--------------|------|
| node1 | 10.5.85.11 | |
| node2 | 10.5.85.12 | |
| node3 | 10.5.85.13 | |
| node4 | 10.5.85.14 | |
| node5 | 10.5.85.15 | A400 |
| node6 | 10.5.85.16 | A400 |
| node7 | 10.5.85.17 | A400 |
### VMs / LXCs
| Name | IP | Gruppe | Zweck |
|-------------|--------------|---------------|------------------------|
| emby-sascha | 10.6.1.103 | media | Emby (Sascha) |
| jellyfin | 10.5.1.112 | media | Jellyfin |
| immich | 10.4.1.107 | media | Immich Fotoverwaltung |
| emby-chris | 10.7.1.106 | media | Emby (Chris) + SMB |
| tdarr | 10.2.1.104 | arr | Tdarr Transcoding |
| arrapps | 10.2.1.100 | arr | Sonarr/Radarr etc. |
| sabnzbd | 10.2.1.119 | arr | SABnzbd |
| dockhand | 10.4.1.116 | docker | Dockhand |
| n8n | 10.4.1.113 | auto | n8n Automation |
| openclaw | 10.4.1.100 | auto | OpenClaw |
| monitoring | 10.1.1.111 | auto | Monitoring Stack |
| automation | 10.1.1.115 | auto | Automation Stack |
| matrix | 10.4.1.110 | communication | Matrix |
### Hetzner
| Name | IP | Zweck |
|-------------|-----------------|--------------------------|
| pfannkuchen | 159.69.245.190 | Caddy Reverse Proxy + VW |
### Hetzner Storagebox
- Host: `u457772-sub3.your-storagebox.de`
- User: `u457772-sub3`
- Port: 23
- SSH Key liegt in `roles/borg/files/` und wird als `/root/.ssh/id_borg` deployed
## Docker Stacks
Jeder Stack hat ein eigenes Git-Repo unter `~/pfannkuchen/github/` und ein eigenes Docker-Netzwerk.
| Stack | VM | Netzwerk | Services |
|------------|--------------|----------------------|-----------------------------------------------------------------|
| pfannkuchen| Hetzner VPS | `proxy_network` | Caddy, Vaultwarden, Homepage |
| monitoring | 10.1.1.111 | `monitoring_network` | Teslamate, Postgres, Grafana, Mosquitto, Prometheus, SNMP-Exporter, InfluxDB, Emby-Exporter, Node-Exporter |
| automation | 10.1.1.115 | `auto_network` | WAHA, Semaphore UI, Patchmon (DB, Redis, Backend, Frontend) |
| n8n | 10.4.1.113 | `n8n_network` | n8n, Postgres |
### Caddy Reverse Proxy (Hetzner VPS)
Caddy läuft auf dem Hetzner VPS und proxied alle Services über WireGuard-IPs:
| Domain | Backend | Bemerkung |
|-------------------------|----------------------------|--------------------|
| tv.sascha-lutz.de | host.docker.internal:18096 | Emby Sascha |
| guck.tv | host.docker.internal:28096 | Emby Chris |
| netzflix.org | host.docker.internal:38096 | Emby Jellyfin |
| vault.sascha-lutz.de | vaultwarden (Container) | Vaultwarden |
| home.sascha-lutz.de | homepage:3000 (Container) | Homepage (Basic Auth) |
| grafana.sascha-lutz.de | grafana:3000 (Container) | Grafana |
| patchmon.sascha-lutz.de | patchmon-frontend:3000 | Patchmon |
| tesla.sascha-lutz.de | teslamate:4000 (Container) | Teslamate (Basic Auth) |
| influx.sascha-lutz.de | influxdb:8086 (Container) | InfluxDB |
| status.guck.tv | 10.200.200.254:3001 | Uptime Kuma |
| n8n.sascha-lutz.de | 10.4.1.113:5678 | n8n |
| docker.sascha-lutz.de | 10.4.1.116:3000 | Dockhand |
| immich.sascha-lutz.de | 10.4.1.107:2283 | Immich |
| dl.guck.tv | 10.2.1.100:5055 | Jellyseerr |
| plappern.com | 10.4.1.110:8008 | Matrix Synapse |
| web.plappern.com | 10.4.1.110:8080 | Matrix Element |
| chat.plappern.com | 10.4.1.110:8090 | Matrix Chat |
| monitor.guck.tv | 10.5.1.102:19999 | Netdata (Basic Auth) |
### Seerr → WhatsApp + Auto-Approve
Kombinierter n8n Workflow der zwei Dinge macht:
**1. Auto-Approve (MEDIA_PENDING):**
```
Jellyseerr → Webhook → n8n → TMDB Genre+FSK Lookup → Kategorisieren → Pfad+Tags setzen → Approve → 20min warten → FHD Radarr/Sonarr Suche
```
Genre-Logik:
| Kategorie | Bedingung | Radarr Pfad | Tag |
|---|---|---|---|
| Horror | Genre "Horror" + FSK ≥ 16 | `/data/UHD/horror` | `horror-4k` |
| Kids | Genre "Animation"/"Family" + FSK ≤ 12 | `/data/UHD/kids-video` | `kids-4k` |
| Normal | Alles andere | `/data/UHD/video` | `video-4k` |
Serien:
| Kategorie | Bedingung | Sonarr Pfad | Tag |
|---|---|---|---|
| Kids | Genre "Animation" + FSK ≤ 12 | `/data/UHD/kids-serien` | `kids-4k` |
| Streaming | Network ist Netflix/HBO/Amazon/Disney+ etc. | `/data/UHD/serien` | `serien-4k` |
| TV | Alles andere | `/data/UHD/tvshows` | `tvshows-4k` |
**2. WhatsApp Newsletter (MEDIA_AVAILABLE):**
```
Jellyseerr → Webhook → n8n → WAHA Session Restart → WAHA sendText → WhatsApp Newsletter
```
- Webhook URL: `http://10.4.1.113:5678/webhook/seerr-notify`
- WAHA: `http://10.1.1.115:3500` (Dashboard: admin / WAHA_API_KEY)
- Newsletter Channel: `120363404705299449@newsletter`
- n8n Workflow: `tmp/n8n-seerr-combined.json`
- Status: **Funktioniert** (Text + Bild-URL, keine eingebetteten Bilder möglich)
### Semaphore UI
Web-UI für Ansible Playbook Management auf `http://10.1.1.115:3000`.
- Login: `admin` / `SEMAPHORE_ADMIN_PASSWORD` (aus `.env`)
- Projekt: Pfannkuchen
- Templates: Setup VM, Update All, Borg Backup, Base Setup, NVIDIA GPU
- Git Repo: `https://github.com/feldjaeger/ansible.git`
### Arr-Stack APIs
| Service | URL | API Key Datei |
|---|---|---|
| Radarr UHD | `http://10.2.1.100:7878` | `tmp/radarr` |
| Radarr FHD | `http://10.2.1.100:7879` | `tmp/radarr1080p` |
| Sonarr UHD | `http://10.2.1.100:8989` | `tmp/sonarr` |
| Sonarr FHD | `http://10.2.1.100:8990` | `tmp/sonarr1080p` |
| Jellyseerr | `http://10.2.1.100:5055` | `tmp/seer` |
| TMDB API | `https://api.themoviedb.org/3` | `tmp/tmdb` (nicht im Repo) |
## ISO Builder
Baut Custom Debian ISOs mit Preseed für unattended Installation. Siehe `iso-builder/README.md`.
```bash
# ISO bauen + auf Proxmox Node uploaden
./iso-builder/build-iso.sh --node 4 --ip 10.4.1.120 --hostname neue-vm
# ISO bauen + VM erstellen + starten
./iso-builder/build-iso.sh --node 4 --ip 10.4.1.120 --hostname neue-vm --create-vm
```
## Netzwerk
### WireGuard Tunnel (Hysteria2)
Alle Proxmox Nodes verbinden sich über Hysteria2 (QUIC) zum VPS. Das umgeht CGNAT-Beschränkungen und versteckt den WireGuard-Traffic vor DPI (Sophos Firewall).
```
[Proxmox Node] → Hysteria2-Client → QUIC (UDP:8443) → Hysteria2-Server (VPS) → WireGuard
```
- Hysteria2 nutzt UDP:8443, Caddy behält TCP:443 + UDP:443 (HTTP/3)
- TLS: Selbstsigniertes Zertifikat auf dem VPS (10 Jahre gültig), Clients mit `insecure: true`
- Bandwidth-Hints konfiguriert für optimale Performance (400 Mbit/s)
| Node | WG-IP | VM-Subnetz | Bemerkung |
|-------|----------------|----------------|------------------|
| VPS | 10.200.200.254 | | WG Server + Hub |
| node1 | 10.200.200.2 | 10.11.1.0/24 | |
| node2 | 10.200.200.3 | 10.2.1.0/24 | Arr-Stack |
| node3 | 10.200.200.113 | 10.3.1.0/24 | |
| node4 | 10.200.200.100 | 10.4.1.0/24 | Docker/Auto |
| node5 | 10.200.200.101 | 10.5.1.0/24 | Media |
| node6 | 10.200.200.116 | 10.6.1.0/24 | A400 |
| node7 | 10.200.200.117 | 10.7.1.0/24 | A400 |
Direkte Peers (kein Hysteria2):
- embyproxy (10.200.200.1)
- Sascha (10.200.200.5), Chris (10.200.200.6), Sascha Handy (10.200.200.7)
- Fassohneboden (10.200.200.4), Marco Minecraft (10.200.200.8)
### Netzwerk-Segmente
| Subnetz | Zweck | Node |
|--------------|----------------|-------|
| 10.5.85.x | Proxmox Hosts | alle |
| 10.1.1.x | Monitoring/Auto| node1 |
| 10.11.1.x | VMs node1 | node1 |
| 10.2.1.x | Arr-Stack | node2 |
| 10.3.1.x | VMs node3 | node3 |
| 10.4.1.x | Docker/Auto | node4 |
| 10.5.1.x | Media VMs | node5 |
| 10.6.1.x | VMs node6 | node6 |
| 10.7.1.x | VMs node7 | node7 |
| 10.200.200.x | WireGuard | VPS |
## Rollen
| Rolle | Zweck |
|---------------------|--------------------------------------------------------------|
| base | Repos, Pakete, Locale, SSH Key, Sudo, QEMU Guest Agent |
| docker | Docker CE + Compose Plugin, User sascha → docker Gruppe |
| nvidia | CUDA Repo, cuda-drivers, Container Toolkit, Docker nvidia-RT |
| borg | SSH Key Deploy, Borg Repo Init, Backup-Script, Systemd Timer |
| hawser | Hawser Install + Systemd Service + Token aus Vault |
| sysctl | BBR, TCP Tuning, Buffer Sizes für Streaming-VMs |
| sysctl_proxmox | Overcommit, File Handles, IP Forward, Bridge-Tuning |
| pve_postinstall | Repos (deb822), Enterprise deaktiviert, Nag-Patch, HA aus |
| pve_gpu_passthrough | IOMMU, VFIO, Nouveau/NVIDIA Blacklist für GPU Passthrough |
| telegraf | InfluxData Repo, Telegraf Config, lm-sensors, Synology SNMP |
| hysteria2 | Hysteria2 Client, Bandwidth-Hints, WireGuard Config |
| hysteria2_server | Hysteria2 Server, selbstsigniertes TLS, systemd Service |
## Playbooks
| Playbook | Wrapper-Befehl | Zweck |
|--------------------------|------------------------|------------------------------------------|
| `site.yml` | `setup <host>` | VM komplett einrichten |
| `base-debian.yml` | `base <host>` | Grundsetup + Docker |
| `nvidia-docker.yml` | `gpu <host>` | NVIDIA Treiber + Docker GPU Runtime |
| `borg-backup.yml` | `backup [host]` | Borg Backup einrichten |
| `hawser.yml` | `hawser <host>` | Hawser installieren |
| `update.yml` | `update [host]` | Dist-Upgrade + Autoremove |
| `sysctl.yaml` | `tune <host>` | Netzwerk-Tuning für Streaming |
| `sysctl-proxmox.yaml` | | Proxmox-Host-Tuning |
| `pve-postinstall.yml` | `pve [host]` | Proxmox Post-Install (Repos, Nag, HA) |
| `pve-gpu-passthrough.yml`| `passthrough [host]` | GPU PCI Passthrough vorbereiten |
| `telegraf.yml` | `telegraf [host]` | Telegraf Monitoring deployen |
| `hysteria2.yml` | | Hysteria2 Client + WireGuard deployen |
| `hysteria2-server.yml` | | Hysteria2 Server auf VPS deployen |
## Inventory-Gruppen
| Gruppe | Hosts | Zweck |
|---------------|-------------------------------------------------|------------------------------|
| proxmox | node1node7 | Alle Proxmox Hosts |
| proxmox_gpu | node2, node4, node6, node7 | Nodes mit A400 GPU |
| nvidia | tdarr, emby-sascha, emby-chris, immich | VMs mit NVIDIA GPU Runtime |
| wireguard | node1node7 | WireGuard Clients |
| media | emby-sascha, jellyfin, immich, emby-chris | Media VMs |
| arr | tdarr, arrapps, sabnzbd | Arr-Stack |
| docker | dockhand | Docker VMs |
| auto | n8n, openclaw, monitoring, automation | Automation |
| communication | matrix | Kommunikation |
| hetzner | pfannkuchen | Hetzner Server |
| frp | emby-sascha, emby-chris, jellyfin | FRP Clients |
| backup | alle (via children) | Borg Backup |
## Borg Backup
Alle Hosts in der Gruppe `backup` bekommen Borg Backup. Die Backup-Quellen sind pro Gruppe konfiguriert:
| Gruppe | Backup-Quellen | Quelle |
|-----------|-----------------------------------------------------------------------------|-------------------------------|
| VMs | `/app-config` | `roles/borg/defaults/main.yml`|
| Proxmox | `/etc/pve /etc/network /etc/wireguard /etc/crontab /etc/fstab /etc/systemd/system/ /etc/iptables /etc/telegraf` | `group_vars/proxmox/borg.yml` |
| Hetzner | `/etc/wireguard /app-config` | `group_vars/hetzner/borg.yml` |
Backup-Script: `/usr/local/bin/borg-backup.sh`
Systemd Timer: täglich 03:00 Uhr (±30min Jitter)
Log: `/var/log/borg-backup.log`
Kompression: lz4
Retention: 7 daily, 4 weekly, 6 monthly
## Telegraf Monitoring
Alle Proxmox Hosts bekommen Telegraf mit InfluxDB v2 Output.
Standard-Inputs: cpu, disk, diskio, kernel, mem, processes, swap, system, nstat, sensors
Sonderfall node2: Zusätzlich Synology NAS SNMP Monitoring (konfiguriert via `host_vars/node2/telegraf.yml`).
## Vault
Vault-Datei: `group_vars/all/vault.yml`
Enthaltene Variablen:
- `vault_hetzner_storage_host` Storagebox Hostname
- `vault_hetzner_storage_user` Storagebox User
- `vault_borg_passphrase` Borg Verschlüsselungspasswort
- `vault_sascha_password` SSH/Become-Passwort für User sascha
- `vault_chris_password` SSH/Become-Passwort für User chris
- `vault_telegraf_influx_token` InfluxDB v2 Token für Telegraf
- `vault_snmp_sec_name` SNMP v3 Security Name (Synology)
- `vault_snmp_auth_password` SNMP v3 Auth Passwort
- `vault_snmp_priv_password` SNMP v3 Privacy Passwort
- `vault_hysteria2_password` Hysteria2 Auth Passwort
- `vault_wireguard_vps_pubkey` WireGuard Public Key des VPS
- `vault_node[1-7]_wg_privkey` WireGuard Private Keys der Nodes
- `vault_hawser_token` Hawser Agent Token für Dockhand
```bash
# Passwörter eintragen und verschlüsseln
ansible-vault edit group_vars/all/vault.yml
ansible-vault encrypt group_vars/all/vault.yml
```
Vault-Passwort liegt in `.vault-password` (in `.gitignore`).
## Verzeichnisstruktur
```
ansible/
├── ansible.cfg
├── pfannkuchen.ini # Inventory
├── pfannkuchen.sh # Wrapper-Script
├── site.yml # Master-Playbook
├── base-debian.yml
├── borg-backup.yml
├── nvidia-docker.yml
├── hawser.yml
├── update.yml
├── sysctl.yaml
├── sysctl-proxmox.yaml
├── pve-postinstall.yml
├── pve-gpu-passthrough.yml
├── telegraf.yml
├── hysteria2.yml
├── hysteria2-server.yml
├── iso-builder/ # Custom Debian ISO Builder
│ ├── build-iso.sh # ISO Build + Upload + VM Create
│ ├── preseed.cfg.tpl # Preseed Template
│ └── output/ # Gebaute ISOs
├── group_vars/
│ ├── all/vault.yml # Vault (verschlüsselt)
│ ├── proxmox/borg.yml # Proxmox Backup-Pfade
│ └── hetzner/borg.yml # Hetzner Backup-Pfade
├── host_vars/
│ ├── node1/wireguard.yml
│ ├── node2/
│ │ ├── telegraf.yml # Synology SNMP
│ │ └── wireguard.yml
│ ├── node3node7/wireguard.yml
│ └── emby_chris/vars.yml # User chris Credentials
├── tmp/
│ ├── n8n-seerr-combined.json # n8n Workflow: Auto-Approve + WhatsApp
│ ├── radarr, sonarr, seer # API Keys
│ ├── radarr1080p, sonarr1080p # FHD API Keys
│ └── n8n # n8n API Key
└── roles/
├── base/tasks/main.yml
├── docker/tasks/main.yml
├── nvidia/{tasks,handlers,defaults}/
├── borg/{tasks,defaults,files,templates}/
├── hawser/tasks/main.yml
├── hawser/handlers/main.yml
├── sysctl/tasks/main.yml
├── sysctl_proxmox/tasks/main.yml
├── pve_postinstall/tasks/main.yml
├── pve_gpu_passthrough/{tasks,handlers}/
├── telegraf/{tasks,handlers,defaults,templates}/
├── hysteria2/{tasks,handlers,defaults}/
└── hysteria2_server/{tasks,handlers,defaults}/
```