CI/CD auf Datenbank und Infrastruktur ausweiten: Ein praktischer Fahrplan

Ihre Anwendungs-Pipeline läuft rund. Code-Änderungen fließen vom Commit in die Produktion – mit automatisierten Tests, Builds und Deployments. Das Team fühlt sich sicher beim Ausrollen von Updates. Aber es gibt ein Problem: Datenbank-Schema-Änderungen passieren immer noch, indem jemand SQL-Skripte direkt in der Produktion ausführt, und Infrastruktur wird konfiguriert, indem man sich in Cloud-Konsolen einloggt und auf Buttons klickt.

Diese Lücke erzeugt Reibung. Ein Entwickler fügt eine neue Spalte zu einer Tabelle hinzu, aber das Migrationsskript wird einem DBA gemailt, der es manuell ausführt. Ein Server braucht eine Konfigurationsänderung, aber jemand muss per SSH einsteigen und Dateien editieren. Diese manuellen Schritte brechen die Konsistenz, die Sie überall sonst aufgebaut haben. Sie bringen Risiken, hinterlassen keine Audit-Trails und machen Rollbacks nahezu unmöglich.

Die gute Nachricht: Dieselben Pipeline-Prinzipien gelten auch für Datenbanken und Infrastruktur. Der Unterschied liegt im Detail: was Sie testen, wie Sie Risiken managen und wie Sie Rollbacks handhaben.

Datenbank-Migrationen in die Pipeline integrieren

Datenbank-Änderungen unterscheiden sich von Anwendungscode, weil sie auf Live-Daten operieren. Ein Bug im Anwendungscode verursacht vielleicht Fehler, die leicht zu beheben sind. Eine schlechte Migration kann Daten korrumpieren oder dauerhaft löschen. Diese Realität macht Teams zögerlich, Datenbank-Deployments zu automatisieren – aber die Alternative, die manuelle Ausführung, ist schlimmer.

Beginnen Sie damit, jede Schema-Änderung als Code zu behandeln. Jede Migration sollte ein Skript sein, das in der Versionskontrolle liegt – entweder im selben Repository wie Ihre Anwendung oder in einem eigenen. Das Skript sollte eine klare Version, eine Beschreibung dessen, was es tut, und ein entsprechendes Rollback-Skript haben.

Eine Migration zum Hinzufügen einer Spalte könnte zum Beispiel so aussehen:

-- V002__add_status_column.sql
-- Forward-Migration: Fügt eine Status-Spalte mit einem Standardwert hinzu
ALTER TABLE users ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active';
-- V002__add_status_column_rollback.sql
-- Rollback-Migration: Entfernt die Status-Spalte
ALTER TABLE users DROP COLUMN status;

Das folgende Diagramm zeigt, wie Datenbank- und Infrastruktur-Stufen in Ihre bestehende Pipeline passen:

flowchart TD A[Code Commit] --> B[Build & Unit Tests] B --> C[Application Deploy to Staging] C --> D[Database Migration Dry Run] D --> E[Infrastructure Provisioning] E --> F[Integration Tests] F --> G{Approval Gate?} G -- Yes --> H[Production Deploy] G -- No --> I[Rollback] H --> J[Database Migration Apply] J --> K[Infrastructure Apply] K --> L[Smoke Tests] L -- Pass --> M[Deploy Complete] L -- Fail --> I I --> N[Restore Previous State]

Ihre Pipeline führt diese Migrationen dann automatisch in allen Umgebungen aus: Entwicklung, Staging und Produktion. Aber weil die Risiken höher sind, brauchen Sie zusätzliche Sicherheitsstufen:

  • Dry Runs im Staging: Bevor Sie eine Migration in der Produktion ausführen, führen Sie sie im Staging mit einer Datenmenge aus, die der Produktion entspricht. Das deckt Performance-Probleme und unerwartetes Locking-Verhalten auf.
  • Kompatibilitätstests: Prüfen Sie, ob die Migration mit vorhandenen Daten funktioniert. Eine Migration, die eine NOT NULL-Spalte ohne Standardwert hinzufügt, schlägt fehl, wenn vorhandene Zeilen in dieser Spalte NULL-Werte haben.
  • Approval-Gates für destruktive Änderungen: Das Löschen einer Spalte, Ändern eines Datentyps oder Entfernen einer Tabelle sollte eine manuelle Freigabe erfordern. Diese Änderungen sind schwer oder gar nicht umkehrbar.

Jede Migration muss ein getestetes Rollback-Skript haben. Eine Spalte hinzuzufügen, ist normalerweise sicher umkehrbar. Eine Tabelle zu löschen, ist es nicht. Ihre Pipeline sollte in der Lage sein, das Rollback automatisch auszuführen, wenn die Migration fehlschlägt oder das Team sich für einen Rückbau entscheidet.

Infrastructure as Code: Deklarieren, nicht klicken

Infrastruktur umfasst Server, Netzwerke, Load Balancer, Datenbank-Instanzen und jede Komponente, die Ihre Anwendung zum Laufen braucht. Wenn Sie diese manuell über Cloud-Konsolen bereitstellen, erzeugen Sie mehrere Probleme:

  • Umgebungen driften auseinander. Die Entwicklung hat möglicherweise leicht andere Einstellungen als die Produktion.
  • Änderungen sind schwer reproduzierbar. Wenn ein Server abstürzt, können Sie ihn exakt nachbauen?
  • Es gibt keinen Audit-Trail. Wer hat letzte Woche die Firewall-Regeln geändert?

Die Lösung: Deklarieren Sie Ihre Infrastruktur als Code. Schreiben Sie Konfigurationsdateien, die beschreiben, wie Ihre Infrastruktur aussehen soll, und lassen Sie die Pipeline diese Konfigurationen anwenden. Das ist Infrastructure as Code (IaC).

Tools wie Terraform, AWS CloudFormation oder Pulumi ermöglichen es Ihnen, Ressourcen in Dateien zu definieren. Diese Dateien durchlaufen dieselbe Pipeline wie Ihr Anwendungscode: Sie kommen in ein Repository, durchlaufen Code-Reviews, werden in der Entwicklung getestet und dann auf Staging und Produktion angewendet.

Infrastruktur zu testen, unterscheidet sich vom Testen von Anwendungen. Anwendungstests prüfen, ob Code sich korrekt verhält. Infrastrukturtests prüfen, ob die Konfiguration die erwartete Umgebung erzeugt:

  • Sind die erforderlichen Ports offen?
  • Ist die Firewall korrekt konfiguriert?
  • Stimmt die Betriebssystemversion?
  • Sind die Ressourcengrößen (CPU, RAM, Festplatte) wie spezifiziert?

Manche Teams gehen noch weiter: Sie stellen die Infrastruktur in einer isolierten Umgebung bereit, führen Tests dagegen aus und zerstören sie dann wieder. Das gibt hohe Sicherheit, bevor Änderungen in der Produktion angewendet werden.

Risiko-Gates für Infrastruktur folgen demselben Muster wie bei Datenbanken. Eine Änderung, die die Festplattengröße anpasst, braucht vielleicht nur automatisierte Tests. Eine Änderung, die das Netzwerk umstrukturiert oder einen Datenbank-Typ ersetzt, benötigt manuelle Freigabe und gründlichere Validierung.

Rollback-Strategien für Datenbank und Infrastruktur

Anwendungscode zurückzurollen ist normalerweise einfach: die vorherige Version ausrollen. Eine Datenbank-Migration oder Infrastruktur-Änderung zurückzurollen, erfordert mehr Planung.

Bei Datenbank-Migrationen muss das Rollback-Skript gleichzeitig mit der Forward-Migration geschrieben werden. Testen Sie das Rollback in Ihrer Pipeline, nicht nur im Kopf. Manche Migrationen sind additiv (eine Spalte hinzufügen) und lassen sich sauber zurückrollen. Andere sind transformativ (eine Tabelle aufteilen) und erfordern sorgfältige Rollback-Logik. Wenn eine Migration nicht sicher zurückgerollt werden kann, ist das ein Signal, den Migrationsansatz zu überdenken.

Bei Infrastruktur sollte Ihre Pipeline den vorherigen Zustand Ihrer Konfiguration speichern. Wenn Sie zurückrollen müssen, wendet die Pipeline die vorherige Konfiguration an. Das funktioniert gut mit deklarativen IaC-Tools, weil sie den Unterschied zwischen aktuellem und gewünschtem Zustand automatisch behandeln.

Praktische Checkliste für den Ausbau Ihrer Pipeline

Bereich Was hinzufügen Risiko-Gate Rollback
Datenbank Migrationsskripte in Versionskontrolle Dry Run im Staging, Freigabe für destruktive Änderungen Getestetes Rollback-Skript pro Migration
Infrastruktur IaC-Konfigurationsdateien Automatisierte Validierung, Freigabe für Architekturänderungen Vorherige Konfiguration gespeichert und ausrollbar

Das Muster wiederholt sich

Sobald Sie Datenbank und Infrastruktur in Ihrer Pipeline haben, werden Sie feststellen, dass sich dasselbe Muster auf andere Bereiche anwenden lässt: Umgebungskonfiguration, Feature Flags, Mobile-App-Releases. Die Details ändern sich – was Sie testen, wie Sie Risiken managen, wie Sie zurückrollen – aber die Kernidee bleibt gleich. Jede Änderung durchläuft einen konsistenten, getesteten, umkehrbaren Pfad.

Beginnen Sie mit einer einzigen Datenbank-Migration in Ihrer Pipeline. Dann mit einer Infrastruktur-Änderung. Die ersten Male werden sich langsam anfühlen, weil Sie den Prozess aufbauen. Aber jede einzelne macht die nächste schneller und sicherer.

Das Ziel ist nicht Automatisierung um ihrer selbst willen. Es geht darum, sicherzustellen, dass Sie – wenn etwas kaputtgeht, und das wird es – genau wissen, was sich geändert hat, wie Sie es beheben und wie Sie verhindern, dass es wieder passiert.