Blue-Green-Deployment funktionierte perfekt. Nur hatte die Green-Umgebung eine andere Config.

Die Ausgangslage:

  • Blue-Umgebung: läuft in Produktion
  • Green-Umgebung: idle, bereit für das Deployment
  • Nach Green deployen, testen, Traffic umschalten

Was schiefging:

Ein Feature Flag war Wochen zuvor in Blue umgelegt worden — direkt, über die Admin-UI. Green fasste niemand an. Als das nächste Release nach Green deployt wurde und der Traffic umschaltete, fiel das Flag still auf seinen alten Wert zurück, und die Nutzer verloren ein Feature, auf das sie sich seit Wochen verlassen hatten. Kein Deploy schlug fehl, kein Alert feuerte; die Umgebung sagte schlicht die Wahrheit über ihre eigene veraltete Config.

Beim Audit fanden wir weiteren Drift:

  • Unterschiedliche Größen der Datenbank-Connection-Pools
  • Unterschiedliche Log-Level
  • Unterschiedliche Timeout-Werte
  • API-Keys nur in Blue rotiert

Der Fix — zwei Arten von Config, zwei Ablageorte:

Die naive Fix-Liste — „Config in Git legen“ und „einen externen Config Store nutzen“ — zeigt in entgegengesetzte Richtungen, bis man trennt, was wohin gehört.

Versionierte Config lebt in Git und wird mit dem Release ausgeliefert. Pool-Größen, Timeouts, Log-Level, Resource Limits: Das sind Eigenschaften eines Releases, also gehören sie als gerenderte Manifeste ins Repo, identisch auf Blue und Green angewendet. Ein GitOps-Controller — Argo CD in unserem Fall, Flux funktioniert genauso gut — vergleicht den Live-Zustand kontinuierlich mit Git, sodass eine Änderung an einer der beiden Umgebungen außerhalb des Prozesses innerhalb von Minuten als Drift auftaucht statt erst beim Cutover. Das ist dieselbe Disziplin, die wir im CI/CD-Pipeline-Design als Grundvoraussetzung behandeln.

Runtime-Toggles leben in einem einzigen gemeinsamen externen Service. Feature Flags dürfen gar nicht erst pro Umgebung existieren. Wir haben sie in einen einzigen Flag-Service (einen OpenFeature-kompatiblen Provider) verschoben, aus dem beide Farben lesen, sodass ein Flag-Wechsel für die Umgebung gilt, die gerade Traffic bedient. Flag-Zustand hat einen Ablageort; Blue und Green sind nur Konsumenten.

Und ein Gate vor jedem Cutover. Die Pipeline vergleicht die gerenderte Config beider Umgebungen und weigert sich bei jedem Delta, den Traffic umzuschalten:

# refuse to cut over if blue and green disagree
diff \
  <(kubectl get cm app-config -n blue -o jsonpath='{.data}') \
  <(kubectl get cm app-config -n green -o jsonpath='{.data}') \
  || { echo "config drift detected - aborting cutover"; exit 1; }

Secrets bekamen dieselbe Behandlung: in einem externen Store rotiert und von einem Operator in beide Umgebungen synchronisiert, nie von Hand „in Blue“ rotiert. Die Datenbankseite von Blue-Green hat ihre eigenen Fallen — siehe unseren Blue-Green-Datenbank-Albtraum.

Lektion: Blue-Green-Deployments erfordern Blue-Green-Config-Management. Eine idle Umgebung driftet standardmäßig; nur Automatisierung merkt es.


← Zurück zu Lessons Learned

Incidents wie dieser sind vermeidbar. Unser AWS Managed Services-Team überwacht Kundenumgebungen 24/7 mit KI-gestütztem Monitoring und Senior Engineers am Pager — damit Geschichten wie diese im Archiv bleiben.