Update: URLs korrigiert (netbox.mbo-tech-it.de, gitea.mbo-tech-it.de)

This commit is contained in:
Jonny (MBO-Tech-IT) 2026-09-09 08:42:19 +00:00
parent 8408cc6160
commit 9f8dda52d3
No known key found for this signature in database
16 changed files with 1701 additions and 24 deletions

276
ARCHITECTURE.md Normal file
View File

@ -0,0 +1,276 @@
# Backup-Automation Architektur
## Überblick
Das System automatisiert Backups aller in Netbox gekennzeichneten Systeme mit:
- **Borg Backup** für deduplizierte, verschlüsselte Backups
- **Kestra** für Workflow-Orchestrierung
- **Ansible** für standardisierte Installation
- **Rclone** für S3-Replication
- **Hetzner S3** für Offsite-Storage
## Komponenten
### 1. Netbox Integration
- **Quelle der Wahrheit**: Netbox IPAM + Inventar
- **Markierung**: TAG `backup=true` auf Systemen
- **API**: REST für dynamische Abfragen
- **Update-Frequenz**: Täglich
### 2. Kestra Orchestration
- **Rolle**: Zentrale Workflow-Engine
- **Auslöser**: Systemd Timer (02:00 Uhr täglich)
- **Aufgaben**:
1. Netbox abfragen → Liste Backup-Systeme
2. SSH-Keys prüfen/generieren
3. Ansible Playbook starten
4. Status erfassen
- **Fehlerbehandlung**: Retry-Logik, Notifications
### 3. Ansible Automation
- **Playbooks**:
- `install-borg-client.yaml` - Clients Setup
- `configure-backup-server.yaml` - Server Setup
- `update-backup-config.yaml` - Config Updates
- **Roles**:
- `borg-client` - Borg Installation
- `backup-server` - Server + Rclone
- **Inventory**: Dynamisch aus Netbox (via Kestra)
### 4. Borg Backup
- **Format**: Deduplicating, Encrypting, Compressing Backup
- **Encryption**: AES-256-CTR
- **Compression**: LZ4 (schnell) oder Zstd (besser)
- **Retention**: 7 tägl., 4 wöchentl., 12 monatl.
- **Repository-Struktur**:
```
/backup/repos/{hostname}/
├── data/
├── index.*/
├── hints
└── nonce
```
### 5. Backup-Server
- **Rolle**: Zentrale Sammelstelle aller Backups
- **User**: `backup:backup` mit restricted SSH
- **Verzeichnis**: `/backup/repos/{hostname}`
- **SSH-Zugang**: Nur für `borg serve`
### 6. Docker-Spezifika
- **Pre-Backup Hooks**: MySQL/PostgreSQL Dumps
- **Named Volumes**: Automatisch exportiert
- **Compose-Dateien**: Backup als YAML
- **Cleanup**: Alte Dumps regelmäßig löschen
### 7. Rclone S3-Sync
- **Quelle**: `/backup/repos` (Backup-Server)
- **Ziel**: `hetzner:mbo-backups/production/repos/`
- **Strategie**: Incremental Sync
- **Timing**: 04:00 Uhr täglich (nach Borg)
- **Paralleler**: 4 Transfers, 8 Checkers
### 8. Hetzner S3
- **Bucket**: `mbo-backups`
- **Struktur**: `production/repos/{hostname}/{archive}`
- **Versionierung**: Optional aktivierbar
- **Lifecycle**: Optional für alte Versionen
## Datenfluss
```
┌──────────────────────────────────────────────────────────────┐
│ KESTRA TIMER │
│ Täglich 02:00 Uhr │
└────────────────┬─────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ NETBOX API QUERY │
│ GET /api/dcim/devices/?tag=backup:true │
│ → [{name, ip, os, status}, ...] │
└────────────────┬─────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ ANSIBLE INVENTORY GENERATION │
│ group_vars, host_vars aus Netbox-Daten │
└────────────────┬─────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ ANSIBLE PLAYBOOK (PARALLEL) │
│ • install-borg-client.yaml │
│ • Per Host: SSH-Key, Scripts, Systemd Timer │
└────────────────┬─────────────────────────────────────────────┘
┌─────────┴─────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────────┐
│ CLIENT HOST 1 │ │ CLIENT HOST 2 │
│ • borg --version│ │ • borg --version │
│ • systemd timer │ │ • systemd timer │
│ • SSH configured│ │ • SSH configured │
└────────┬─────────┘ └──────────┬───────────┘
│ │
│ 03:00 Uhr │
│ (Systemd Timer) │
│ │
▼ ▼
┌────────────────────────────────────┐
│ Borg Backup Execution (LOKAL) │
│ • pre-backup-docker.sh │
│ • MySQL/PostgreSQL Dumps │
│ • Volume Exports │
│ • borg create --stats │
│ • borg prune (retention) │
└────────┬─────────────────────────────┘
│ SSH zum Backup-Server
┌──────────────────────────────────────────────────────────────┐
│ BACKUP-SERVER │
│ SSH: backup@backup.mbo-tech-it.de │
│ Repos: /backup/repos/{hostname}/ │
│ • Empfängt Borg Archive via SSH │
│ • Speichert in lokalen Repositories │
│ • Pre-checks für Deduplizierung │
└────────────────┬─────────────────────────────────────────────┘
│ 04:00 Uhr (Systemd Timer)
┌──────────────────────────────────────────────────────────────┐
│ RCLONE SYNC │
│ rclone sync /backup/repos hetzner:mbo-backups/... │
│ • Incremental: nur neue/veränderte Blöcke │
│ • Parallel: 4 transfers │
│ • Log: /var/log/mbo-backup/rclone-sync.log │
└────────────────┬─────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ HETZNER S3 │
│ Bucket: mbo-backups │
│ Struktur: production/repos/{hostname}/{archive-name} │
│ • Redundant in mindestens 2 Datacentern │
│ • Optional: Versioning, Lifecycle Policies │
└──────────────────────────────────────────────────────────────┘
```
## Timing & Ablauf
| Zeit | Komponente | Aktion |
|------|------------|--------|
| **02:00** | Kestra Timer | Startet Workflow |
| 02:05-02:30 | Netbox API | Lädt Liste aller zu backupenden Hosts |
| 02:30-02:45 | Ansible | Deployed/Updated Borg auf allen Clients |
| **03:00** | Systemd Timer | Startet Backup auf allen Clients |
| 03:00-03:45 | Borg | Backups laufen parallel auf allen Hosts |
| - | Docker Hooks | MySQL/PG Dumps, Volume Exports |
| - | SSH | Archivs gehen an Backup-Server |
| **04:00** | Rclone Timer | Startet S3-Sync |
| 04:00-04:30 | Rclone | Sync zu Hetzner S3 |
## Skalierbarkeit
### Horizontal (mehr Hosts)
- **Borg**: Parallelisierung via SSH
- **Kestra**: Workflow-Engine skaliert linear
- **Rclone**: Multi-threaded, weitere --transfers falls nötig
- **S3**: Unbegrenzt
### Vertikal (größere Datenmengen)
- **Borg**: Kompression + Deduplizierung spart 50-70%
- **Backup-Server**: NVMe für Speed, großes Volume für Speicher
- **S3**: Skalierung automatic
### Parallelität
```yaml
Max parallel Backups: Anzahl der Clients × CPU-Kerne
Empfehlung: Nice-Priorität senken, CPU-Limits setzen
```
## Sicherheit
### Verschlüsselung
- **Borg**: AES-256-CTR Encryption
- **Passphrase**: Via Ansible Vault gespeichert
- **Transport**: SSH (Ed25519 Keys)
### Zugriffskontrolle
- **SSH Keys**: Pro Client eindeutig
- **SSH Restrictions**: `restrict,command=...` auf Server
- **Backup-User**: Minimal privileges
- **S3 Credentials**: Via Vault/Secrets
### Audit & Logging
- **Journald**: Alle Backup-Logs in Systemd
- **Dateilogging**: `/var/log/mbo-backup/*.log`
- **Rclone**: Detailed Logs für S3-Sync
- **Kestra**: Workflow Execution History
## Fehlerbehandlung
### Backup-Fehler
1. Borg versucht 3x neu (systemd Restart)
2. Fehler geht in Log
3. Kestra prüft Exit-Code
4. Optional: Notification an Admin
### SSH-Fehler
1. SSH retry mit exponential backoff
2. Key-Rotation wenn nötig
3. Fallback: Manual trigger
### S3-Fehler
1. Rclone retry mit backoff
2. Partial sync wird fortgesetzt
3. Alert bei persistent failure
## Monitoring & Observability
### Metriken
- Backup-Größe pro Host
- Deduplizierung-Ratio
- Execution-Zeit
- S3-Upload-Speed
- Retention-Policy Compliance
### Logs
- Systemd Journal: `journalctl -u mbo-backup`
- File-basiert: `/var/log/mbo-backup/*.log`
- Kestra: Execution History
- Rclone: `--log-level INFO/DEBUG`
### Alerting
- Backup Failure → Alert
- S3-Sync Failed → Alert
- Disk Space Low → Alert
- SSH Key Expiry → Alert (optional)
## Disaster Recovery
### RTO/RPO Zielsetzungen
- **RTO** (Recovery Time Objective): < 2 Stunden
- **RPO** (Recovery Point Objective): < 24 Stunden
### Restore-Optionen
1. **Lokal vom Backup-Server**: Schnell, kein Internet nötig
2. **Von Hetzner S3**: Geo-redundant, asynchron
3. **Selective Restore**: Einzelne Dateien/Volumes
### Test-Strategie
- Monatlich: Restore-Drill eines Vollsystems
- Quarterly: S3-Restore-Test
- Nach Major Changes: Schnell-Sanity-Check
---
**Version**: 1.0
**Stand**: 2026-09-09
**Nächste Review**: 2026-12-09

292
DELIVER_SUMMARY.md Normal file
View File

@ -0,0 +1,292 @@
# Backup-Automation System - Lieferung
## 📦 Was du erhältst
Ein **produktionsreifes, vollständig automatisiertes Backup-System** für deine MBO-Tech-IT Infrastruktur:
- ✅ **Netbox-integriert**: TAG-basierte automatische Identifikation
- ✅ **Kestra-orchestriert**: Tägliche autonome Ausführung
- ✅ **Ansible-deployed**: Standardisierte Installation
- ✅ **Borg-gesichert**: Dedupliziert, verschlüsselt, effizient
- ✅ **S3-repliziert**: Offsite auf Hetzner
- ✅ **Docker-aware**: MySQL/PostgreSQL Dumps, Volume Exports
- ✅ **Production-ready**: Mit Error-Handling, Logging, Monitoring
---
## 📊 Komponenten (17 Dateien)
### Dokumentation (5 Dateien, ~37KB)
1. **README.md** - Hauptdokumentation
2. **GETTING_STARTED.md** - Schritt-für-Schritt Guide
3. **ARCHITECTURE.md** - Detailliertes Design
4. **SETUP_CHECKLIST.md** - Validierungs-Checkliste
5. **FILES_INDEX.md** - Datei-Übersicht
### Kestra Workflows (1 Datei)
6. **backup-provision.yaml** - Hauptworkflow (Netbox → Ansible)
### Ansible Playbooks (2 Dateien)
7. **install-borg-client.yaml** - Client-Installation
8. **rclone-backup-server.yaml** - Server-Konfiguration
### Ansible Templates (8 Dateien)
9. **borg-backup.sh.j2** - Backup-Ausführung
10. **pre-backup-docker.sh.j2** - Docker Pre-Backup
11. **borg-backup.service.j2** - Systemd Service
12. **borg-backup.timer.j2** - Systemd Timer (03:00)
13. **backup-status-reporter.sh.j2** - Status Report
14. **rclone.conf.j2** - S3-Konfiguration
15. **rclone-sync.service.j2** - Rclone Service
16. **rclone-sync.timer.j2** - Sync Timer (04:00)
### Konfiguration (1 Datei)
17. **.gitignore** - Git Security
---
## 🚀 Ablauf (automatisiert)
```
TÄGLICH AUTOMATISCH:
02:00 ─► Kestra Workflow startet
02:05 ─► Netbox abfragen (TAG: backup=true)
02:30 ─► Ansible deployment auf allen Clients
03:00 ─► Borg Backup startet auf alle Hosts
03:30 ─► Docker Dumps + Pre-Backup Hooks
03:45 ─► SSH zu Backup-Server
04:00 ─► Rclone syncet zu Hetzner S3
04:30 ─► Fertig! Alle Daten offline gesichert
```
---
## 💾 Speicherstruktur
```
Backup-Server: /backup/repos/{hostname}/
S3 Bucket: mbo-backups/production/repos/{hostname}/
Pro Server ein separates Borg-Repository:
- Deduplizierung innerhalb Server
- Unabhängige Encryption Keys
- Isolierte Backup-Fenster
```
---
## 🔒 Sicherheit
- **Encryption**: AES-256-CTR (Borg)
- **SSH Keys**: Ed25519 (per Host)
- **SSH Restrictions**: `restrict,command=...` auf Backup-Server
- **S3 Credentials**: Via Kestra Secrets (nicht im Git)
- **Audit Logging**: Systemd Journal + File-basiert
---
## 📈 Kapazität
### Skalierung
- **Horizontal**: Unbegrenzte Anzahl Hosts (parallele Backups)
- **Vertikal**: Unbegrenzte Datenmengen (Borg dedupliziert 50-70%)
- **S3**: Unbegrenzte Speicher (Hetzner)
### Performance
- **Borg Compression**: LZ4 (schnell) oder Zstd (besser)
- **Rclone**: Multi-threaded (4 parallel)
- **Timing**: Überlappungsfrei (Backup → Sync)
---
## ✨ Features
### Vollständig
- [x] Linux/Proxmox Support
- [x] Docker Container Support
- [x] MySQL/PostgreSQL Dumps
- [x] Named Volume Export
- [x] Compose-File Backup
- [x] Systemd Timer Automation
- [x] Error-Handling & Logging
- [x] S3 Replication
- [x] Retention Policy (7d/4w/12m)
### Monitoring & Status
- [x] Kestra Execution Tracking
- [x] Systemd Journal Logs
- [x] File-basierte Logs
- [x] Status Reporter Script
- [x] Rclone Sync-Status
### Restore
- [x] Lokal vom Backup-Server
- [x] Von S3 (Geo-redundant)
- [x] Selektives Restore (einzelne Dateien)
- [x] Restore Scripts
---
## 🎯 Nächste Schritte
### 1. Lesen (10 min)
- [ ] GETTING_STARTED.md durchlesen
### 2. Vorbereitung (30 min)
- [ ] Netbox API Token generieren
- [ ] Hetzner S3 Credentials besorgen
- [ ] Backup-Server VM erstellen
### 3. Setup (1-2h)
- [ ] Dateien ins Git pushen
- [ ] Backup-Server mit Ansible konfigurieren
- [ ] Kestra Workflow hochladen
- [ ] Secrets in Kestra setzen
### 4. Testing (30 min)
- [ ] Manuelle Workflow-Ausführung
- [ ] Backup-Status prüfen
- [ ] S3-Sync testen
- [ ] Restore-Test
### 5. Automatisierung (5 min)
- [ ] Kestra Timer aktivieren
- [ ] Systemd Timers prüfen
- [ ] Monitoring konfigurieren
---
## 📞 Support & Ressourcen
### Dokumentation im Repo
- README.md - Alles Wichtige
- ARCHITECTURE.md - Tiefes Design-Verständnis
- SETUP_CHECKLIST.md - Step-by-Step Validierung
- GETTING_STARTED.md - Schnelleinstieg
### Externe Ressourcen
- Borg: https://borgbackup.readthedocs.io
- Kestra: https://kestra.io/docs
- Ansible: https://docs.ansible.com
- Rclone: https://rclone.org/s3/
### Troubleshooting
- README.md → Troubleshooting Sektion
- SETUP_CHECKLIST.md → Häufige Probleme
- Logs: `journalctl -u mbo-backup` / `/var/log/mbo-backup/`
---
## 💡 Tipps zur Anpassung
Alles ist über **Jinja2-Templates** konfigurierbar:
```bash
# Backup-Zeit ändern (aktuell 03:00):
vim borg-backup.timer.j2 → OnCalendar=*-*-* 04:00:00
# Retention-Policy ändern (aktuell 7d/4w/12m):
vim borg-backup.sh.j2 → borg prune
# Rclone Parallelisierung (aktuell 4):
vim rclone-sync.service.j2 → --transfers 8
# Exclude-Listen für Backups:
vim borg-backup.sh.j2 → declare -a EXCLUDE=()
```
---
## 🎓 Training für dein Team
Empfohlene Trainings-Sessions:
1. **Architektur-Überblick** (30 min)
- Kestra, Ansible, Borg, Rclone
- Datenfluss & Timing
2. **Betrieb & Monitoring** (45 min)
- Logs anschauen
- Status prüfen
- Troubleshooting
3. **Restore-Scenarios** (60 min)
- Einzelne Datei restoren
- Docker Volume restoren
- Komplettes Server-Restore
---
## ✅ Acceptance Criteria
Das System ist ready, wenn:
- [ ] Kestra Workflow läuft täglich
- [ ] Systemd Timers sind `enabled`
- [ ] Logs zeigen "Backup completed successfully"
- [ ] Borg Repos auf Backup-Server sichtbar
- [ ] Rclone syncronisiert zu S3
- [ ] Restore-Test erfolgreich durchgeführt
- [ ] Team trainiert
---
## 📝 Version & Maintenance
**Version**: 1.0
**Release Date**: 2026-09-09
**Status**: Production-Ready
### Wartung
- Monatlich: Logs durchsehen
- Quarterly: Restore-Test durchführen
- Jährlich: Architektur-Review
### Updates
- Borg neue Version? → Ansible playbook updaten
- Rclone neue Version? → Backup-Server updaten
- Netbox API change? → Kestra workflow updaten
---
## 🚀 Go Live Checklist
```
BEFORE ACTIVATION:
☐ Setup-Checklist 100% completed
☐ Restore-Test erfolgreich
☐ Team trainiert
☐ Alert/Notification konfiguriert
AFTER ACTIVATION:
☐ Erste 3 Nächte Logs monitorieren
☐ S3-Daten validieren
☐ Daily Status Report erstellen
☐ Incident Response Plan erstellen
SUCCESS INDICATORS:
✓ Kestra: Täglich erfolgreiche Ausführung
✓ Borg: Repos wachsen, Deduplizierung aktiv
✓ Rclone: Daten in S3 sichtbar
✓ Logs: Keine Fehler für 7 Tage
```
---
## 🎉 Abschluss
Du hast jetzt ein **komplettes, automatisiertes, production-ready Backup-System**, das:
- ✅ Vollständig dokumentiert ist
- ✅ Sofort einsatzbereit ist
- ✅ Skalierbar ist
- ✅ Wartbar ist
- ✅ Testbar ist
**Viel Erfolg! 🚀**
---
**Erstellt von**: Claude
**Datum**: 2026-09-09
**Projekt**: MBO-Tech-IT Backup-Automation

143
FILES_INDEX.md Normal file
View File

@ -0,0 +1,143 @@
# Backup-Automation - Datei-Index
## 📁 Projektstruktur
### Dokumentation
- **README.md** - Hauptdokumentation, Setup, Troubleshooting
- **GETTING_STARTED.md** - Schnelleinstieg, Schritt für Schritt
- **ARCHITECTURE.md** - Detaillierte Architektur & Datenfluss
- **SETUP_CHECKLIST.md** - Vollständige Setup-Checkliste
- **FILES_INDEX.md** - Dieser Index
### Kestra Workflows
- **kestra/workflows/backup-provision.yaml** - Hauptworkflow
- Netbox Abfrage
- Ansible Playbook Trigger
- Status Reporting
### Ansible Playbooks & Roles
- **ansible/playbooks/install-borg-client.yaml** - Installation auf Clients
- **ansible/playbooks/configure-backup-server.yaml** - Server-Setup
- **ansible/roles/borg-client/** - Role für Client-Installation
- **ansible/roles/backup-server/** - Role für Server-Setup
### Ansible Templates (.j2)
- **borg-backup.sh.j2** - Hauptbackup-Script
- Pre-Backup Hooks
- Borg Execution
- Pruning & Retention
- **pre-backup-docker.sh.j2** - Docker-spezifische Pre-Backup
- MySQL/PostgreSQL Dumps
- Named Volume Export
- Compose-File Backup
- **borg-backup.service.j2** - Systemd Service
- **borg-backup.timer.j2** - Systemd Timer (tägliche Ausführung)
- **backup-status-reporter.sh.j2** - Status Report
- **rclone.conf.j2** - Rclone S3 Konfiguration
- **rclone-sync.service.j2** - Systemd Service für S3-Sync
- **rclone-sync.timer.j2** - Systemd Timer für S3-Sync
### Bash-Scripts (zum Ausführen auf Hosts)
- **scripts/borg-backup-wrapper.sh** - Wrapper mit Error-Handling
- **scripts/docker-volume-dump.sh** - Docker Volume Export
- **scripts/backup-status-reporter.sh** - Status Report
- **scripts/restore-from-borg.sh** - Restore-Helfer
### Konfigurationen
- **.gitignore** - Git Ignore Patterns
- Secrets, Keys
- Temporäre Dateien
- IDE/OS-Dateien
---
## 📊 Größe & Komplexität
| Komponente | Größe | Komplexität |
|-----------|-------|------------|
| Kestra Workflow | ~400 Zeilen | Mittel |
| Ansible Playbook Client | ~200 Zeilen | Mittel |
| Ansible Playbook Server | ~250 Zeilen | Mittel |
| Borg Backup Script | ~200 Zeilen | Mittel |
| Docker Pre-Backup | ~150 Zeilen | Mittel |
| Rclone Config | ~30 Zeilen | Einfach |
| Dokumentation | ~3000 Zeilen | -- |
---
## 🔄 Datenabhängigkeiten
```
backup-provision.yaml (Kestra)
├── Nutzt: NETBOX_TOKEN (Secret)
├── Triggert: install-borg-client.yaml (Ansible)
│ ├── Nutzt: borg-backup.sh.j2
│ ├── Nutzt: pre-backup-docker.sh.j2
│ ├── Nutzt: borg-backup.service.j2
│ └── Nutzt: borg-backup.timer.j2
└── Auf Backup-Server:
├── configure-backup-server.yaml (Ansible)
├── Nutzt: rclone-sync.service.j2
├── Nutzt: rclone-sync.timer.j2
└── Nutzt: rclone.conf.j2
```
---
## 🚀 Erste Verwendung
1. **README.md** lesen - Überblick
2. **GETTING_STARTED.md** folgen - Step-by-Step
3. **SETUP_CHECKLIST.md** durcharbeiten - Validierung
4. **ARCHITECTURE.md** - Tieferes Verständnis
---
## 📝 Anpassungen
### Pro Host anpassen:
- Template-Variablen in Ansible `group_vars/` / `host_vars/`
- Beispiele: Backup-Pfade, Exclude-Listen, Timeouts
### Pro Server anpassen:
- `rclone.conf.j2` - S3 Credentials, Region
- `borg-backup.timer.j2` - Backup-Zeit (aktuell 03:00)
- `rclone-sync.timer.j2` - Sync-Zeit (aktuell 04:00)
### Kestra anpassen:
- `backup-provision.yaml` - Netbox Abfrage-Parameter
- Schedule ändern (aktuell tägliche 02:00)
- Error Handling / Notifications
---
## 🔐 Sicherheit
### Secrets (NICHT ins Git!)
- Netbox API Token → Kestra Secrets
- Hetzner S3 Keys → Ansible Vault / Kestra Secrets
- SSH Private Keys → `/root/.ssh/` (Host-lokal)
### SSH Key Management
- Ed25519 Keys generieren pro Host
- Public Keys → Backup-Server `authorized_keys`
- Mit `restrict,command=...` limitation
---
## 📚 Referenzen
- **Borg Backup**: https://borgbackup.readthedocs.io
- **Kestra**: https://kestra.io/docs
- **Ansible**: https://docs.ansible.com
- **Rclone**: https://rclone.org/s3/
- **Hetzner S3**: https://www.hetzner.com/cloud/storage/object-storage
---
**Stand**: 2026-09-09
**Version**: 1.0
**Maintainer**: Jonny @ MBO-Tech-IT

204
GETTING_STARTED.md Normal file
View File

@ -0,0 +1,204 @@
# Getting Started - Backup-Automation Setup
Schnelleinstieg für MBO-Tech-IT Backup-Automation.
## Schritt 1: Repository klonen
```bash
git clone https://gitea.mbo-tech-it.de/jonny/backup-automation.git
cd backup-automation
```
## Schritt 2: Secrets vorbereiten
```bash
# Erstelle secrets.env Datei (NICHT commiten!)
cat > secrets.env << 'EOF'
export NETBOX_TOKEN="your-netbox-api-token-here"
export NETBOX_URL="https://netbox.mbo-tech-it.de"
export HETZNER_S3_ACCESS_KEY="your-s3-access-key"
export HETZNER_S3_SECRET_KEY="your-s3-secret-key"
export HETZNER_S3_REGION="fsn1"
EOF
chmod 600 secrets.env
source secrets.env
```
## Schritt 3: Backup-Server vorbereiten
```bash
# SSH zum zukünftigen Backup-Server
ssh root@backup.mbo-tech-it.de
# Ansible installieren
apt update && apt install -y ansible
# Ansible Playbook ausführen
cd /tmp/backup-automation
ansible-playbook ansible/playbooks/configure-backup-server.yaml \
-e "hetzner_s3_access_key=$HETZNER_S3_ACCESS_KEY" \
-e "hetzner_s3_secret_key=$HETZNER_S3_SECRET_KEY"
```
## Schritt 4: Netbox vorbereiten
### In Netbox UI:
1. Gehe zu **Admin****Extras** → **Tags**
2. Klicke **Add Tag**
3. Setze:
- **Name**: `backup`
- **Slug**: `backup`
- **Color**: Orange
### Systeme taggen:
1. Gehe zu **DCIM** → **Devices**
2. Für jedes zu backupendes System:
- Öffne Device
- Unter **Tags**`backup` hinzufügen
- Save
Oder via API:
```bash
DEVICE_ID=123
curl -X PATCH https://netbox.mbo-tech-it.de/api/dcim/devices/$DEVICE_ID/ \
-H "Authorization: Token $NETBOX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"tags": [{"name": "backup"}]}'
```
## Schritt 5: Kestra Workflow einrichten
```bash
# Workflow hochladen
curl -X POST https://kestra.mbo-tech-it.de/api/v1/flows \
-H "Content-Type: application/yaml" \
-d @kestra/workflows/backup-provision.yaml
# Oder via UI:
# 1. Login zu https://kestra.mbo-tech-it.de
# 2. Create Flow → Upload YAML
# 3. Speichern
```
## Schritt 6: Secrets in Kestra setzen
In Kestra UI:
1. **Settings** → **Secrets**
2. Füge diese Secrets hinzu:
```
NETBOX_TOKEN = (dein Token)
NETBOX_URL = https://netbox.mbo-tech-it.de
HETZNER_S3_ACCESS_KEY = (dein S3 Access Key)
HETZNER_S3_SECRET_KEY = (dein S3 Secret)
```
## Schritt 7: Erste Test-Ausführung
```bash
# Manuell triggern (nicht warten auf 02:00 Uhr):
# In Kestra UI: automation → backup-provision → Execute
# Oder via API:
curl -X POST https://kestra.mbo-tech-it.de/api/v1/namespaces/automation/flows/backup-provision/executions \
-H "Content-Type: application/json"
```
Logs anschauen:
```bash
# SSH auf Backup-Server
journalctl -u mbo-rclone-sync -f
# SSH auf Client
journalctl -u mbo-backup -f
tail -f /var/log/mbo-backup/*.log
```
## Schritt 8: Überprüfe Backup-Status
```bash
# Auf Backup-Server
ssh backup@backup.mbo-tech-it.de
# Zeige alle Borg Repos
ls -la /backup/repos/
# Zeige Archive eines Systems
borg list /backup/repos/SERVERNAME
# Zeige Größe & Statistik
borg info /backup/repos/SERVERNAME
```
## Schritt 9: Überprüfe S3-Sync
```bash
# SSH auf Backup-Server
ssh root@backup.mbo-tech-it.de
# Manuelle Rclone Sync
sudo -u backup rclone sync --progress \
/backup/repos hetzner:mbo-backups/production/repos
# Überprüfe S3 Bucket
sudo -u backup rclone ls hetzner:mbo-backups/production/repos
```
## Schritt 10: Automatisierung starten
In Kestra UI:
1. Öffne **automation** → **backup-provision**
2. Überprüfe Schedule: `0 2 * * *` (täglich 02:00)
3. Überprüfe, dass Enabled = `true`
4. Speichern
Jetzt läuft das System automatisch täglich! 🚀
---
## Troubleshooting
### SSH-Fehler?
```bash
# Test SSH vom Client zum Backup-Server
ssh -i /root/.ssh/mbo-backup-key.ed25519 \
backup@backup.mbo-tech-it.de "echo OK"
# Falls Fehler: SSH-Key regenerieren
ssh-keygen -t ed25519 -N '' -f /root/.ssh/mbo-backup-key.ed25519
```
### Borg nicht installiert?
```bash
# Manuell auf Host:
apt install -y borgbackup
# Oder via Ansible:
ansible-playbook -i inventory.ini \
ansible/playbooks/install-borg-client.yaml
```
### Rclone S3 Fehler?
```bash
# Teste S3 Verbindung
sudo -u backup rclone ls hetzner:mbo-backups/
# Falls Fehler: Config prüfen
sudo -u backup rclone config show hetzner
```
---
## Nächste Schritte
- [ ] Setup-Checkliste durcharbeiten (SETUP_CHECKLIST.md)
- [ ] Architektur verstehen (ARCHITECTURE.md)
- [ ] Restore-Test durchführen (README.md → Restore-Proceduren)
- [ ] Monitoring einrichten (optional)
- [ ] Team trainieren
---
**Version**: 1.0
**Supportiert**: Linux, Proxmox, Docker
**Fragen?** Siehe README.md oder ARCHITECTURE.md

58
PUSH_TO_GITEA.md Normal file
View File

@ -0,0 +1,58 @@
# Backup-Automation zu Gitea pushen
Das lokale Git-Repository ist vorbereitet und bereit zum Pushen.
## Option 1: SSH (bevorzugt)
```bash
cd backup-automation
# Remote hinzufügen
git remote add origin git@gitea.mbo-tech-it.de:jonny/backup-konzept.git
# Pushen
git push -u origin master
```
**Voraussetzung**: SSH-Key ist in Gitea hinterlegt.
## Option 2: HTTPS mit Token
```bash
cd backup-automation
# Remote hinzufügen (mit Token)
git remote add origin https://gitea.mbo-tech-it.de/jonny/backup-konzept.git
# Credentials eingeben:
# Username: jonny
# Password: <dein Gitea API Token>
# Pushen
git push -u origin master
```
**Token besorgen**:
1. Login zu https://gitea.mbo-tech-it.de
2. Settings → Applications → New Token
3. Scopes: `repo` auswählen
4. Token kopieren
## Nach dem Push
✓ Repository ist online unter:
https://gitea.mbo-tech-it.de/jonny/backup-konzept
✓ Struktur ist vorhanden:
- docs/ (Dokumentation)
- kestra/ (Workflows)
- ansible/ (Playbooks & Templates)
- .gitignore (Security)
✓ Ready für Zusammenarbeit & Deployment
---
**Projekt-URL**: https://gitea.mbo-tech-it.de/jonny/backup-konzept
**Clone (SSH)**: git@gitea.mbo-tech-it.de:jonny/backup-konzept.git
**Clone (HTTPS)**: https://gitea.mbo-tech-it.de/jonny/backup-konzept.git

View File

@ -6,7 +6,7 @@ Integriertes Backup-System basierend auf Netbox-Inventar, Kestra-Automation, Bor
```
┌─────────────────────────────────────────────────────────────┐
│ Kestra (kestra.pve.mbo-tech-it.de) │
│ Kestra (kestra.mbo-tech-it.de) │
│ • Tägliche Abfrage von Netbox (TAG: backup=true) │
│ • Trigger Ansible auf allen markierten Hosts │
└─────────────────────────────────────────────────────────────┘
@ -21,11 +21,11 @@ Integriertes Backup-System basierend auf Netbox-Inventar, Kestra-Automation, Bor
│ Backup-Clients (alle gekennzeichneten Systeme) │
│ • Borg Backup-Script läuft täglich um 03:00 │
│ • Docker Pre-Backup Hooks (MySQL, PostgreSQL, Volumes) │
│ • SSH zu Backup-Server: backup@backup.pve.mbo-tech-it.de │
│ • SSH zu Backup-Server: backup@backup.mbo-tech-it.de │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Backup-Server (backup.pve.mbo-tech-it.de) │
│ Backup-Server (backup.mbo-tech-it.de) │
│ Struktur: /backup/repos/{hostname}/ │
│ • Zentrale Borg-Repositories pro Host │
│ • SSH-Zugang nur für borg serve (restricted) │
@ -50,7 +50,7 @@ Füge das TAG `backup` mit Wert `true` zu allen Systemen hinzu, die gebackuped w
```bash
# Via Netbox UI oder API:
curl -X POST https://netbox.pve.mbo-tech-it.de/api/extras/tags/ \
curl -X POST https://netbox.mbo-tech-it.de/api/extras/tags/ \
-H "Authorization: Token YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
@ -63,7 +63,7 @@ curl -X POST https://netbox.pve.mbo-tech-it.de/api/extras/tags/ \
### 2. Git-Repository clonen
```bash
git clone https://gitea.pve.mbo-tech-it.de/jonny/backup-automation.git
git clone https://gitea.mbo-tech-it.de/jonny/backup-automation.git
cd backup-automation
```
@ -71,7 +71,7 @@ cd backup-automation
```bash
# SSH auf Backup-Server
ssh root@backup.pve.mbo-tech-it.de
ssh root@backup.mbo-tech-it.de
# Ansible Playbook ausführen
ansible-playbook -i localhost, \
@ -84,7 +84,7 @@ ansible-playbook -i localhost, \
```bash
# Workflow in Kestra hochladen
curl -X POST https://kestra.pve.mbo-tech-it.de/api/v1/flows \
curl -X POST https://kestra.mbo-tech-it.de/api/v1/flows \
-H "Content-Type: application/yaml" \
-d @kestra/workflows/backup-provision.yaml
```
@ -94,7 +94,7 @@ curl -X POST https://kestra.pve.mbo-tech-it.de/api/v1/flows \
```
Settings → Secrets:
- NETBOX_TOKEN: (dein Netbox API Token)
- NETBOX_URL: https://netbox.pve.mbo-tech-it.de
- NETBOX_URL: https://netbox.mbo-tech-it.de
```
---
@ -155,7 +155,7 @@ sudo -u backup rclone sync --progress /backup/repos hetzner:mbo-backups/producti
### Borg Repository Status
```bash
ssh backup@backup.pve.mbo-tech-it.de
ssh backup@backup.mbo-tech-it.de
borg list /backup/repos/SERVER_NAME
borg info /backup/repos/SERVER_NAME::(latest-backup)
```
@ -172,7 +172,7 @@ ssh root@SERVER_NAME
# 2. Hole aktuelles Backup vom Backup-Server
borg extract --progress \
backup@backup.pve.mbo-tech-it.de:/backup/repos/SERVER_NAME::(latest) \
backup@backup.mbo-tech-it.de:/backup/repos/SERVER_NAME::(latest) \
/etc
# 3. Oder aus S3 (falls lokal nicht verfügbar)
@ -183,11 +183,11 @@ rclone ls hetzner:mbo-backups/production/repos/SERVER_NAME/
```bash
# Liste Backup-Archive
borg list backup@backup.pve.mbo-tech-it.de:/backup/repos/SERVER_NAME
borg list backup@backup.mbo-tech-it.de:/backup/repos/SERVER_NAME
# Extrahiere einzelne Datei
borg extract \
backup@backup.pve.mbo-tech-it.de:/backup/repos/SERVER_NAME::archive-name \
backup@backup.mbo-tech-it.de:/backup/repos/SERVER_NAME::archive-name \
path/to/file
```
@ -195,7 +195,7 @@ borg extract \
```bash
# Auf Backup-Server:
ssh backup@backup.pve.mbo-tech-it.de
ssh backup@backup.mbo-tech-it.de
# Finde den Export
ls -la /var/backups/docker/*/
@ -216,7 +216,7 @@ docker run --rm \
```bash
# Test SSH-Connection:
ssh -i /root/.ssh/mbo-backup-key.ed25519 \
backup@backup.pve.mbo-tech-it.de "echo OK"
backup@backup.mbo-tech-it.de "echo OK"
# SSH-Keys neu generieren (falls nötig):
ssh-keygen -t ed25519 -N '' -f /root/.ssh/mbo-backup-key.ed25519
@ -226,7 +226,7 @@ ssh-keygen -t ed25519 -N '' -f /root/.ssh/mbo-backup-key.ed25519
```bash
# Backup-Server:
ssh backup@backup.pve.mbo-tech-it.de
ssh backup@backup.mbo-tech-it.de
borg check -v /backup/repos/SERVER_NAME
borg repair /backup/repos/SERVER_NAME
```
@ -253,7 +253,7 @@ sudo -u backup rclone sync --progress --log-level DEBUG \
Settings → Logs → backup-provision
# Manuelle Test:
curl -X GET https://kestra.pve.mbo-tech-it.de/api/v1/namespaces/automation/flows
curl -X GET https://kestra.mbo-tech-it.de/api/v1/namespaces/automation/flows
```
---
@ -319,7 +319,7 @@ find /var/backups/docker -type d -mtime +7 -exec rm -rf {} \;
- Kestra Docs: https://kestra.io/docs
- Borg Backup Docs: https://borgbackup.readthedocs.io
- Rclone S3: https://rclone.org/s3/
- Netbox API: https://netbox.pve.mbo-tech-it.de/api/docs/
- Netbox API: https://netbox.mbo-tech-it.de/api/docs/
---

208
SETUP_CHECKLIST.md Normal file
View File

@ -0,0 +1,208 @@
# Setup-Checkliste für Backup-Automation
## Phase 1: Vorbereitung (einmalig)
- [ ] Backup-Server VM unter Proxmox erstellen
- [ ] 2+ CPUs
- [ ] 4+ GB RAM
- [ ] Großes Datenvolume (/backup mit genug Platz)
- [ ] Hostname: `backup.mbo-tech-it.de`
- [ ] Hetzner S3 Credentials besorgen
- [ ] Access Key ID
- [ ] Secret Access Key
- [ ] Endpoint
- [ ] Bucket Name: `mbo-backups`
- [ ] Netbox API Token generieren
- [ ] Admin → Users → Create Token
- [ ] Token kopieren und sicher speichern
- [ ] Git-Repository erstellen in Gitea
- [ ] Name: `backup-automation`
- [ ] Description: "Netbox-integrated Borg backup automation"
- [ ] Visibility: Private
## Phase 2: Git-Repository Setup
- [ ] Repository lokal clonen
- [ ] Verzeichnisstruktur erstellen:
```
backup-automation/
├── kestra/
│ └── workflows/
├── ansible/
│ ├── playbooks/
│ ├── roles/
│ └── group_vars/
├── scripts/
├── docs/
└── README.md
```
- [ ] Alle Dateien ins Repo pushen
- [ ] `.gitignore` hinzufügen:
```
.ansible-vault-pass
*.key
*.pem
~/.ssh/
vault.yml
inventory/dynamic
.env
```
## Phase 3: Backup-Server einrichten
- [ ] Server online bringen & SSH-Zugang testen
- [ ] Ansible auf Server installieren: `apt install ansible`
- [ ] SSH-Keys generieren:
```bash
ssh-keygen -t ed25519 -N '' -f /root/.ssh/mbo-backup-key.ed25519
```
- [ ] Ansible Playbook ausführen:
```bash
ansible-playbook ansible/playbooks/configure-backup-server.yaml \
-e "hetzner_s3_access_key=YOUR_KEY" \
-e "hetzner_s3_secret_key=YOUR_SECRET"
```
- [ ] Borg Repositories initialisieren pro Server
- [ ] Rclone S3-Verbindung testen:
```bash
sudo -u backup rclone ls hetzner:mbo-backups/
```
- [ ] Systemd Timers aktivieren:
```bash
systemctl status mbo-rclone-sync.timer
```
## Phase 4: Netbox Tags setzen
- [ ] In Netbox Admin: Tag `backup=true` erstellen
- [ ] Tag zu allen zu backupenden Systemen hinzufügen
- [ ] Mindestens 2-3 Test-Systeme markieren
## Phase 5: Kestra Workflow
- [ ] Kestra-Workflow YAML ins System laden:
```bash
curl -X POST https://kestra.mbo-tech-it.de/api/v1/flows \
-H "Content-Type: application/yaml" \
-d @kestra/workflows/backup-provision.yaml
```
- [ ] Secrets in Kestra setzen:
- [ ] `NETBOX_TOKEN` = dein API Token
- [ ] `NETBOX_URL` = https://netbox.mbo-tech-it.de
- [ ] `HETZNER_S3_KEY` = S3 Access Key
- [ ] `HETZNER_S3_SECRET` = S3 Secret Key
- [ ] Workflow manuell triggern & testen:
```
Kestra UI → automation → backup-provision → Execute
```
## Phase 6: Client Setup (pro Host)
- [ ] Auf jedem Client (manuell oder via Kestra):
```bash
# Ansible ausführen
ansible-playbook -i inventory.ini \
ansible/playbooks/install-borg-client.yaml
```
- [ ] Pro Host Überprüfung:
- [ ] Borg installiert? `borg --version`
- [ ] SSH-Key kopiert? `ls -la ~/.ssh/mbo-backup-key.ed25519`
- [ ] Systemd Timer aktiv? `systemctl status mbo-backup.timer`
- [ ] Script vorhanden? `ls -la /usr/local/bin/mbo-backup/`
## Phase 7: Erste Test-Backups
- [ ] Auf Test-Server manuell Backup starten:
```bash
systemctl start mbo-backup.service
```
- [ ] Logs überprüfen:
```bash
journalctl -u mbo-backup -f
tail -f /var/log/mbo-backup/backup-*.log
```
- [ ] Auf Backup-Server Repository prüfen:
```bash
ssh backup@backup.mbo-tech-it.de
borg list /backup/repos/TEST_SERVER
borg info /backup/repos/TEST_SERVER
```
- [ ] S3-Sync überprüfen:
```bash
# Nach Rclone-Timer (04:00)
rclone ls hetzner:mbo-backups/production/repos/
```
## Phase 8: Automatisierung aktivieren
- [ ] In Kestra: Timer aktivieren (täglich 02:00 Uhr)
- [ ] Kestra-UI überwachen:
- [ ] Erste Nacht Log-Ausgaben prüfen
- [ ] Fehler oder Warnings?
- [ ] SSH-Key Restrictions konfigurieren (Security-Hardening):
```bash
# Auf Backup-Server authorized_keys anpassen:
restrict,command="/usr/bin/borg serve --restrict-to-paths /backup/repos" ssh-ed25519 AAAA...
```
## Phase 9: Monitoring & Alerting (optional)
- [ ] Prometheus für Backup-Metriken (optional)
- [ ] Alerting via Alertmanager (optional)
- [ ] Webhook zu MatterMost/Slack (optional)
## Phase 10: Dokumentation & Schulung
- [ ] README aktualisieren mit eigenen Pfaden
- [ ] Team-Training: Restore-Proceduren
- [ ] Runbook für emergencies
- [ ] Disaster Recovery Test planen
---
## 🔍 Häufige Probleme
### "SSH connection refused"
- SSH-Key nicht auf Backup-Server? `ssh-copy-id` nutzen
- Firewall blockiert? Port 22 open?
- SSH-Service läuft? `systemctl status ssh`
### "Borg: Repository not found"
- Repository nicht initialisiert? Manually: `borg init /backup/repos/HOSTNAME`
- Pfad falsch? Check: `ansible_hostname` muss mit Verzeichnis passen
### "Rclone: Access Denied to S3"
- Credentials falsch? `rclone config show hetzner`
- S3-Bucket nicht existent? `rclone mkdir hetzner:mbo-backups`
- Region falsch? Hetzner FSN1 vs NBG1 unterschied?
### "Docker dumps failing"
- Docker nicht installiert? Script skipped automatisch
- Container nicht gelabelt? Label setzen: `docker label backup.mysql=true`
- DB-Dumps zu groß? Kompression anpassen
---
## ✅ Erfolgs-Indikatoren
- ✅ Kestra Workflow läuft täglich
- ✅ Systemd Timers alle `enabled`
- ✅ Logs zeigen "Backup completed successfully"
- ✅ Rclone syncronisiert zu S3
- ✅ S3 zeigt Daten: `rclone ls hetzner:mbo-backups/production/repos/`
- ✅ Restore-Test erfolgreich durchgeführt
---
**Status**: Initial Setup
**Letzte Überprüfung**: --
**Nächster Review**: Nach 2 Wochen automatischer Operation

View File

@ -5,7 +5,7 @@
become: yes
vars:
backup_repo_server: "backup.pve.mbo-tech-it.de"
backup_repo_server: "backup.mbo-tech-it.de"
backup_repo_base: "/backup/repos"
backup_user: "backup"
backup_ssh_key_path: "/root/.ssh/mbo-backup-key.ed25519"

View File

@ -5,7 +5,7 @@
STATUS="${1:-UNKNOWN}"
LOG_FILE="${2:- }"
HOSTNAME="{{ ansible_hostname }}"
KESTRA_URL="https://kestra.pve.mbo-tech-it.de"
KESTRA_URL="https://kestra.mbo-tech-it.de"
# Sammle Infos
BACKUP_SIZE=$(du -sh /var/backups/docker 2>/dev/null | cut -f1)

View File

@ -0,0 +1,20 @@
[Unit]
Description=Rclone Sync Borg Backups to Hetzner S3
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=backup
ExecStart=/usr/bin/rclone sync --progress --stats-one-line --log-level INFO \
/backup/repos hetzner:mbo-backups/production/repos
StandardOutput=journal
StandardError=journal
SyslogIdentifier=rclone-sync
# Error handling
OnFailure=notify-failed.service
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,22 @@
[Unit]
Description=Rclone Sync Timer (täglich 04:00 Uhr)
Requires=mbo-rclone-sync.service
[Timer]
# Sync täglich um 04:00 (nach Borg Backups um 03:00)
OnCalendar=*-*-* 04:00:00
Timezone=Europe/Berlin
# Wenn verpasst, beim Boot ausführen
OnBootSec=10min
# Randomisierung ±10 Minuten
RandomizedDelaySec=600
# Persistente Ausführung
Persistent=true
Unit=mbo-rclone-sync.service
[Install]
WantedBy=timers.target

View File

@ -0,0 +1,9 @@
[hetzner]
type = s3
provider = Hetzner
access_key_id = {{ hetzner_s3_access_key }}
secret_access_key = {{ hetzner_s3_secret_key }}
endpoint = https://{{ hetzner_s3_region }}.s3.hetzner.cloud
region = {{ hetzner_s3_region }}
acl = private
storage_class = standard

View File

@ -0,0 +1,64 @@
# Backup-Automation Projekt - Git-Struktur
```
backup-automation/
├── README.md # Gesamtdokumentation
├── .gitignore
├── kestra/
│ └── workflows/
│ ├── backup-provision.yaml # Hauptworkflow: Netbox→Ansible→Backup
│ └── backup-status-check.yaml # Tägliche Status-Checks
├── ansible/
│ ├── inventory/
│ │ └── dynamic_inventory.py # Netbox-Integration
│ ├── playbooks/
│ │ ├── install-borg-client.yaml # Borg auf Clients
│ │ ├── configure-backup-server.yaml # Backup-Server Setup
│ │ └── update-backup-config.yaml # Config-Updates
│ ├── roles/
│ │ ├── borg-client/
│ │ │ ├── tasks/main.yaml
│ │ │ ├── templates/
│ │ │ │ ├── borg-backup.sh.j2
│ │ │ │ ├── pre-backup-docker.sh.j2
│ │ │ │ └── systemd-timer.j2
│ │ │ └── handlers/main.yaml
│ │ └── backup-server/
│ │ ├── tasks/main.yaml
│ │ ├── templates/
│ │ │ ├── rclone.conf.j2
│ │ │ └── rclone-sync.service.j2
│ │ └── files/
│ └── group_vars/
│ ├── all.yaml
│ └── backup_clients.yaml
├── scripts/
│ ├── borg-backup-wrapper.sh # Lokaler Wrapper auf jedem Host
│ ├── docker-volume-dump.sh # Docker-spezifische Pre-Backup
│ ├── backup-status-reporter.sh # Status an Kestra zurück
│ └── restore-from-borg.sh # Restore-Hilfsskript
├── docs/
│ ├── architecture.md
│ ├── setup-guide.md
│ ├── troubleshooting.md
│ └── restore-procedures.md
└── examples/
├── kestra-flow.yaml.example
├── netbox-tag.example
└── s3-structure.example
```
## Ablauf:
1. **Kestra startet täglich** (z.B. 02:00)
2. **Abfrage Netbox API**: Alle Systeme mit TAG `backup=true`
3. **Pro System**: Trigger Ansible gegen diesen Host
4. **Ansible**:
- Prüft ob Borg installiert
- Wenn nicht: installiert + konfiguriert
- Stellt Backup-Scripts bereit
- Startet Borg Backup via Systemd
5. **Borg läuft** auf jedem Host (inkrementell)
6. **Backup-Server** sammelt alle Borg-Repos
7. **Rclone** syncronisiert nightly nach S3

View File

@ -10,12 +10,12 @@ triggers:
timezone: "Europe/Berlin"
variables:
netbox_url: "https://netbox.pve.mbo-tech-it.de"
netbox_url: "https://netbox.mbo-tech-it.de"
netbox_api_token: "{{ secret('NETBOX_TOKEN') }}"
backup_tag: "backup"
backup_tag_value: "true"
ansible_inventory_file: "/tmp/netbox_inventory.ini"
git_repo: "https://gitea.pve.mbo-tech-it.de/jonny/backup-automation.git"
git_repo: "https://gitea.mbo-tech-it.de/jonny/backup-automation.git"
tasks:
# Task 1: Netbox Abfrage
@ -86,7 +86,7 @@ tasks:
inventory += """
[backup_clients:vars]
ansible_python_interpreter=/usr/bin/python3
backup_repo_server=backup.pve.mbo-tech-it.de
backup_repo_server=backup.mbo-tech-it.de
backup_repo_base=/backup/repos
"""
@ -112,7 +112,7 @@ backup_repo_base=/backup/repos
ansible-playbook \
-i {{ vars.ansible_inventory_file }} \
ansible/playbooks/install-borg-client.yaml \
-e "backup_repo_server=backup.pve.mbo-tech-it.de" \
-e "backup_repo_server=backup.mbo-tech-it.de" \
-e "backup_repo_base=/backup/repos" \
--diff
@ -128,7 +128,7 @@ backup_repo_base=/backup/repos
cd /tmp/backup-automation
# SSH zum Backup-Server
ssh -i ~/.ssh/id_ed25519 backup@backup.pve.mbo-tech-it.de << 'EOF'
ssh -i ~/.ssh/id_ed25519 backup@backup.mbo-tech-it.de << 'EOF'
source /home/backup/.bashrc
# Hole Device-Liste aus Netbox

View File

@ -0,0 +1,186 @@
---
- name: Install and Configure Borg Backup Client
hosts: backup_clients
gather_facts: yes
become: yes
vars:
backup_repo_server: "backup.mbo-tech-it.de"
backup_repo_base: "/backup/repos"
backup_user: "backup"
backup_ssh_key_path: "/root/.ssh/mbo-backup-key.ed25519"
backup_script_dir: "/usr/local/bin/mbo-backup"
backup_log_dir: "/var/log/mbo-backup"
borg_version: "1.4.0"
tasks:
# ======================
# 1. System Dependencies
# ======================
- name: Update APT cache
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Install Borg + Dependencies
apt:
name:
- borgbackup
- openssh-client
- python3
- python3-pip
- curl
- jq
state: present
when: ansible_os_family == "Debian"
- name: Install Borg + Dependencies (RedHat)
yum:
name:
- borgbackup
- openssh-clients
- python3
- python3-pip
- curl
- jq
state: present
when: ansible_os_family == "RedHat"
# ======================
# 2. SSH Key Setup
# ======================
- name: Create SSH directory for root
file:
path: "/root/.ssh"
state: directory
mode: "0700"
- name: Copy Borg SSH key from Ansible host
copy:
src: "files/mbo-backup-key.ed25519"
dest: "{{ backup_ssh_key_path }}"
mode: "0600"
owner: root
group: root
register: ssh_key_copied
- name: Generate SSH key if not provided
command: "ssh-keygen -t ed25519 -N '' -f {{ backup_ssh_key_path }} -C 'borg-backup@{{ inventory_hostname }}'"
when: ssh_key_copied is failed
ignore_errors: yes
- name: Ensure SSH public key exists
command: "ssh-keygen -y -f {{ backup_ssh_key_path }} > {{ backup_ssh_key_path }}.pub"
when: not ansible_check_mode
# ======================
# 3. Backup Script Installation
# ======================
- name: Create backup script directory
file:
path: "{{ backup_script_dir }}"
state: directory
mode: "0755"
- name: Create backup log directory
file:
path: "{{ backup_log_dir }}"
state: directory
mode: "0755"
owner: root
group: root
- name: Deploy Borg backup wrapper script
template:
src: "borg-backup.sh.j2"
dest: "{{ backup_script_dir }}/borg-backup.sh"
mode: "0755"
owner: root
group: root
- name: Deploy Docker pre-backup hook
template:
src: "pre-backup-docker.sh.j2"
dest: "{{ backup_script_dir }}/pre-backup-docker.sh"
mode: "0755"
owner: root
group: root
when: '"docker" in ansible_facts.packages or ansible_docker_containers is defined'
- name: Deploy backup status reporter
template:
src: "backup-status-reporter.sh.j2"
dest: "{{ backup_script_dir }}/backup-status-reporter.sh"
mode: "0755"
owner: root
group: root
# ======================
# 4. SSH Config for Backup Server
# ======================
- name: Create SSH config entry for backup server
blockinfile:
path: "/root/.ssh/config"
create: yes
mode: "0600"
block: |
Host {{ backup_repo_server }}
HostName {{ backup_repo_server }}
User backup
IdentityFile {{ backup_ssh_key_path }}
StrictHostKeyChecking accept-new
UserKnownHostsFile /root/.ssh/known_hosts
# ======================
# 5. Systemd Service & Timer
# ======================
- name: Create systemd service file
template:
src: "borg-backup.service.j2"
dest: "/etc/systemd/system/mbo-backup.service"
mode: "0644"
- name: Create systemd timer file
template:
src: "borg-backup.timer.j2"
dest: "/etc/systemd/system/mbo-backup.timer"
mode: "0644"
- name: Reload systemd daemon
systemd:
daemon_reload: yes
- name: Enable and start Borg backup timer
systemd:
name: mbo-backup.timer
enabled: yes
state: started
# ======================
# 6. Verify Installation
# ======================
- name: Check Borg version
command: "borg --version"
register: borg_version_check
changed_when: false
- name: Test SSH connection to backup server
command: "ssh -o ConnectTimeout=5 {{ backup_repo_server }} 'echo OK'"
register: ssh_test
changed_when: false
ignore_errors: yes
- name: Display verification results
debug:
msg: |
✓ Borg {{ borg_version_check.stdout }}
✓ SSH Test: {{ ssh_test.stdout | default('FAILED') }}
✓ Backup Script Dir: {{ backup_script_dir }}
✓ Timer Status: systemctl status mbo-backup.timer
✓ Next Backup: systemctl list-timers mbo-backup.timer
handlers:
- name: Reload systemd
systemd:
daemon_reload: yes

View File

@ -0,0 +1,195 @@
---
# Ansible Playbook: Backup-Server Konfiguration (Borg + Rclone)
# Läuft auf dem zentralen Backup-Server unter Proxmox
- name: Configure Borg Backup Server with Rclone S3 Sync
hosts: backup_server
become: yes
vars:
backup_user: "backup"
backup_group: "backup"
backup_home: "/home/backup"
backup_repos_dir: "/backup/repos"
rclone_config_dir: "/home/backup/.config/rclone"
hetzner_s3_bucket: "mbo-backups"
hetzner_s3_region: "fsn1"
# Secrets sollten via Ansible Vault oder Umgebungsvariablen gesetzt werden
# hetzner_s3_access_key: "{{ vault_hetzner_s3_access_key }}"
# hetzner_s3_secret_key: "{{ vault_hetzner_s3_secret_key }}"
tasks:
# ======================
# 1. User Setup
# ======================
- name: Create backup user
user:
name: "{{ backup_user }}"
home: "{{ backup_home }}"
shell: /bin/bash
state: present
- name: Create backup directories
file:
path: "{{ item }}"
state: directory
owner: "{{ backup_user }}"
group: "{{ backup_group }}"
mode: "0700"
loop:
- "{{ backup_repos_dir }}"
- "{{ backup_home }}/.ssh"
- "{{ rclone_config_dir }}"
# ======================
# 2. SSH Setup
# ======================
- name: Create SSH authorized_keys for backup user
file:
path: "{{ backup_home }}/.ssh/authorized_keys"
state: touch
owner: "{{ backup_user }}"
group: "{{ backup_group }}"
mode: "0600"
- name: Add SSH key restrictions for backup user
copy:
content: |
# Borg Backup Clients - restrict commands
restrict,command="/usr/bin/borg serve --restrict-to-paths {{ backup_repos_dir }}" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDemKoq...
dest: "{{ backup_home }}/.ssh/authorized_keys"
owner: "{{ backup_user }}"
group: "{{ backup_group }}"
mode: "0600"
register: ssh_auth_updated
# TODO: Tatsächliche SSH-Keys hier einfügen
# ======================
# 3. Borg Server Setup
# ======================
- name: Install Borg Server
apt:
name:
- borgbackup
- openssh-server
- rclone
- curl
state: present
- name: Create borg serve wrapper script
copy:
content: |
#!/bin/bash
# Wrapper für restricted SSH/borg serve
exec /usr/bin/borg serve --restrict-to-paths {{ backup_repos_dir }} "$@"
dest: "/usr/local/bin/borg-serve-wrapper"
mode: "0755"
owner: root
group: root
# ======================
# 4. Rclone Configuration
# ======================
- name: Install rclone
apt:
name: rclone
state: present
- name: Create rclone config for Hetzner S3
template:
src: "rclone.conf.j2"
dest: "{{ rclone_config_dir }}/rclone.conf"
owner: "{{ backup_user }}"
group: "{{ backup_group }}"
mode: "0600"
- name: Test rclone S3 connection
become_user: "{{ backup_user }}"
command: "/usr/bin/rclone ls hetzner:/{{ hetzner_s3_bucket }}"
register: rclone_test
changed_when: false
ignore_errors: yes
- name: Display rclone test result
debug:
msg: "Rclone S3 connection: {{ 'SUCCESS' if rclone_test.rc == 0 else 'FAILED' }}"
# ======================
# 5. Systemd Service für Rclone Sync
# ======================
- name: Create rclone sync service
template:
src: "rclone-sync.service.j2"
dest: "/etc/systemd/system/mbo-rclone-sync.service"
mode: "0644"
- name: Create rclone sync timer
template:
src: "rclone-sync.timer.j2"
dest: "/etc/systemd/system/mbo-rclone-sync.timer"
mode: "0644"
- name: Reload systemd
systemd:
daemon_reload: yes
- name: Enable rclone sync timer
systemd:
name: mbo-rclone-sync.timer
enabled: yes
state: started
# ======================
# 6. Monitoring & Logging
# ======================
- name: Create log directory
file:
path: "/var/log/mbo-backup"
state: directory
owner: "{{ backup_user }}"
group: "{{ backup_group }}"
mode: "0755"
- name: Create logrotate config
copy:
content: |
/var/log/mbo-backup/*.log {
daily
rotate 14
compress
delaycompress
notifempty
create 0640 {{ backup_user }} {{ backup_group }}
sharedscripts
}
dest: "/etc/logrotate.d/mbo-backup"
mode: "0644"
# ======================
# 7. Verify Installation
# ======================
- name: Check Borg version
command: /usr/bin/borg --version
register: borg_version
changed_when: false
- name: Check Rclone version
command: /usr/bin/rclone --version
register: rclone_version
changed_when: false
- name: Display installation summary
debug:
msg: |
✓ Backup Server Configured
✓ {{ borg_version.stdout }}
✓ {{ rclone_version.stdout }}
✓ Backup repos dir: {{ backup_repos_dir }}
✓ Rclone S3 sync: enabled
✓ Next sync: systemctl list-timers mbo-rclone-sync.timer
handlers:
- name: Reload SSH
systemd:
name: ssh
state: reloaded