# 🔄 GitOps ConfigMap Auto-Sync via Checksums

Dieses Dokument erklärt ein Kernproblem mit **Flux CD** und **externe Konfigurationen** – und wie wir es gelöst haben.

---

## 📋 Das Problem: Flux erkennt ConfigMap-Änderungen nicht

### Die Situation

Unsere HelmRelease (`element-server-suite.yaml`) nutzt `valuesFrom`, um Konfigurationen aus externen **ConfigMaps** zu laden:

```yaml
spec:
  valuesFrom:
    - kind: ConfigMap
      name: ess-element-custom     # ← Diese ConfigMap
      valuesKey: values.yaml
    - kind: ConfigMap
      name: ess-synapse-custom     # ← Diese ConfigMap
      valuesKey: values.yaml
```

Diese ConfigMaps entstehen aus Dateien im Git-Repo (`apps/production/custom-configs/*.yaml`) und werden von Kustomize in den Cluster deployed.

### Das Kernproblem

**Flux CD reagiert NICHT automatisch, wenn sich eine ConfigMap ändert.**

Warum? Flux überwacht nur das Git-Repository auf Änderungen. Wenn du `element-values.yaml` änderst:

1. ✅ Flux sieht die Änderung im Git-Repo
2. ✅ Kustomize erzeugt eine neue ConfigMap mit den neuen Werten
3. ❌ Aber Helm (der Helm-Controller in Flux) erkennt **nicht**, dass sich die externe ConfigMap geändert hat
4. ❌ Helm deployt das Chart nicht neu → Die alten Themes/Configs bleiben aktiv

Das ist kein Bug, sondern by-design: Helm achtet nur auf:
- Chart-Version (z.B. `26.4.0`)
- Änderungen in den direkten `values:` Blöcken
- Nicht auf externe Quellen wie ConfigMaps

---

## 🔑 Die Lösung: Checksums als Trigger

Wir nutzen **Annotations mit Checksums** als Workaround:

```yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  annotations:
    element-config-checksum: "401f8a87d0ef5d91d2e5032d4aede42c"  # ← Hash der element-values.yaml
    synapse-config-checksum: "e98fe81141f52e7ea833596ca39853b9"  # ← Hash der synapse-values.yaml
```

Wenn sich der Annotation-Wert ändert, sieht Flux, dass die **HelmRelease selbst** sich geändert hat – und deployt neu.

### Automatisierung via Git Pre-Commit Hook

Das Problem: Wer aktualisiert die Checksums, wenn man `element-values.yaml` editiert?

**Lösung:** Ein Git **pre-commit Hook** tut das automatisch:

```bash
$ vi apps/production/custom-configs/element-values.yaml
# (Farbe ändern, Theme hinzufügen, …)

$ git add apps/production/custom-configs/element-values.yaml
$ git commit -m "feat: new theme"
# ← Der Hook läuft jetzt:
#   1. Berechnet MD5-Hash der neuen element-values.yaml
#   2. Aktualisiert die Annotation in kustomization.yaml
#   3. Added kustomization.yaml zum Commit automatisch
```

Der User muss **nichts Zusätzliches tun** – alles läuft automatisch.

---

## 🚀 Installation

Nach dem Repository **klonen**, führe dieses Skript aus:

```bash
cd prod/gitops
./scripts/install-hooks.sh
```

Das Skript:
- ✅ Erstellt einen Symlink `.git/hooks/pre-commit` → `scripts/hooks/pre-commit`
- ✅ Macht die Hook-Datei ausführbar
- ✅ Gibt dir eine Bestätigungsmeldung

**Einmalig pro lokales Repository.** Neue Klone müssen den Hook auch installieren.

---

## 📝 Workflow: ConfigMaps ändern

So sieht die Praxis aus:

### 1️⃣ Änderung machen

```bash
vi apps/production/custom-configs/element-values.yaml
# Edit: Themes, Farben, Logging-Level, etc.
```

### 2️⃣ Committen (Hook läuft automatisch)

```bash
git add apps/production/custom-configs/element-values.yaml
git commit -m "feat: add Dark Purple theme variant"

# Pre-Commit Hook läuft automatisch:
# → Berechnet neuen Hash
# → Updated kustomization.yaml
# → Added kustomization.yaml zum Commit
```

### 3️⃣ Überprüfung (optional)

```bash
# Schaue, was committet wird:
git show --stat

# Output sollte zeigen:
#   element-values.yaml (modified)
#   kustomization.yaml (modified) ← vom Hook hinzugefügt
```

### 4️⃣ Pushen & Deployen

```bash
git push
# ← Flux sieht die Änderung an kustomization.yaml
# ← HelmRelease wird neu-synced mit den neuen Checksums
# ← Die neue Config ist in ~5 Minuten aktiv
```

---

## 🔧 Technische Details

### Welche Dateien sind "überwacht"?

Der Hook beobachtet:

| Datei | Annotation | Ziel |
|-------|-----------|------|
| `apps/production/custom-configs/element-values.yaml` | `element-config-checksum` | Element Web Themes, Branding |
| `apps/production/custom-configs/synapse-values.yaml` | `synapse-config-checksum` | Synapse Logging, Federation |

### Hook-Implementation

Der Hook (`scripts/hooks/pre-commit`) macht folgendes:

1. Prüft, ob eine der überwachten Dateien geändert wurde (`git diff --cached`)
2. Berechnet den MD5-Hash der Datei (kompatibel mit macOS/Linux)
3. Ersetzt den Hash-Wert in `apps/production/kustomization.yaml` via `sed`
4. Added `kustomization.yaml` automatisch zum Commit mit `git add`

```bash
# Beispiel: element-values.yaml ändert sich von
value: "401f8a87d0ef5d91d2e5032d4aede42c" # element-config
# zu
value: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" # element-config
```

---

## ⚠️ Häufige Fragen

### F: Was passiert, wenn der Hook fehlschlägt?

A: Der Commit wird **abgebrochen**. Du siehst eine Fehlermeldung. Typische Gründe:
- `md5` oder `md5sum` nicht installiert (sehr unwahrscheinlich)
- `sed` Syntax-Fehler (sehr selten)

Lass dich nicht entmutigen – rufe denen auf, die das Setup machen 🚀

### F: Kann ich den Hook deaktivieren?

A: Ja, aber bitte nicht! Wenn du temporär ohne Hook arbeiten möchtest:

```bash
git commit --no-verify
```

Das umgeht den Hook einmalig. Danach musst du die Checksums manuell aktualisieren.

### F: Der Hook touched `kustomization.yaml`, obwohl ich sie nicht editiert habe?

A: Das ist **Absicht**. Der Hook updated **nur** die Checksums, nicht den Rest der Datei. Das ist sauber und Git-freundlich.

### F: Was wenn ich mehrere ConfigMaps gleichzeitig ändere?

A: Der Hook aktualisiert **alle** deren Checksums in einem Pass. Keine Probleme.

---

## 🧪 Verifikation: Hook funktioniert?

Teste es selbst:

```bash
# 1. Hook installieren
./scripts/install-hooks.sh

# 2. Eine Teständerung machen
echo "# Test" >> apps/production/custom-configs/element-values.yaml

# 3. Committen
git add apps/production/custom-configs/element-values.yaml
git commit -m "test: verify hook"

# 4. Überprüfung: Wurde kustomization.yaml auto-updated?
git diff HEAD~1 apps/production/kustomization.yaml | grep -i checksum

# Output sollte zeigen, dass ein Checksum sich geändert hat
```

Wenn ja → Hook funktioniert! ✅  
Wenn nein → Rufe uns an 📞

---

## 📚 Zusammenhang mit Flux CD

```
┌─────────────────────────────────────────────────────────────┐
│ Git Repository (axion1337.chat-gitops)                      │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  apps/production/custom-configs/                            │
│  ├── element-values.yaml (du änderst das)                   │
│  ├── synapse-values.yaml                                    │
│  └── mas-secret.yaml                                        │
│                                                              │
│  apps/production/                                           │
│  └── kustomization.yaml (Hook updated die Checksums hier)   │
│                                                              │
│  apps/production/                                           │
│  └── element-server-suite.yaml (HelmRelease mit Annotations)│
│                                                              │
└─────────────────────────────────────────────────────────────┘
                            ↓ git push
┌─────────────────────────────────────────────────────────────┐
│ FluxCD im Kubernetes-Cluster                                │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│ 1. GitRepository Source                                     │
│    └─ Fetcht dein Repo alle 10 Minuten                      │
│                                                              │
│ 2. Kustomization production-apps                            │
│    └─ Applyt die Kustomize-Overlays                         │
│    └─ Erzeugt ConfigMaps mit neuen Werten                   │
│                                                              │
│ 3. HelmRelease matrix-stack                                 │
│    └─ Sieht neue Annotations (Checksums)                    │
│    └─ Deployt Helm-Chart mit neuen Werten                   │
│                                                              │
│ 4. Element Web Pods                                         │
│    └─ Restarten automatisch                                 │
│    └─ Laden neue Config aus der ConfigMap                   │
│                                                              │
└─────────────────────────────────────────────────────────────┘
```

---

## 🚨 Notfall: Manuelle Checksum-Aktualisierung

Falls der Hook ausfällt (z.B. weil Git Hooks in CI deaktiviert sind), kannst du Checksums manuell aktualisieren:

```bash
# 1. Neuen Hash berechnen
md5sum apps/production/custom-configs/element-values.yaml
# Output: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6  apps/production/custom-configs/element-values.yaml

# 2. Annotation in kustomization.yaml updaten
vi apps/production/kustomization.yaml
# Ändere: value: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" # element-config

# 3. Committen
git add apps/production/kustomization.yaml
git commit -m "fix: manual checksum update"
git push
```

---

**Version:** 1.0  
**Letztes Update:** 2026-05-14  
**Kompatibilität:** FluxCD 2.x, Kustomize 5.x+
