Jenseits des Anwendungscodes: CI/CD für Konfiguration, Mobile und Feature Flags erweitern
Sie haben CI/CD-Pipelines für Ihren Anwendungscode, Datenbankmigrationen und die Infrastrukturbereitstellung am Laufen. Deployments laufen reibungsloser, Rollbacks sind schneller, und Ihr Team schläft nachts besser. Aber da ist dieses nagende Gefühl, dass noch etwas fehlt.
Das Problem zeigt sich in kleinen Dingen. Ein Teammitglied muss einen Datenbank-Verbindungsstring für die Staging-Umgebung ändern. Die Korrektur ist trivial – nur ein Konfigurationswert – aber es erfordert einen vollständigen Deployment-Zyklus, weil die Konfiguration im Code eingebettet ist. Oder Ihr Mobile-Team veröffentlicht eine neue Version, aber die App-Store-Überprüfung dauert drei Tage, und niemand hat mit dieser Verzögerung gerechnet. Oder eine Funktion, die schrittweise für Benutzer ausgerollt werden sollte, ist entweder vollständig aktiv oder vollständig deaktiviert, weil es keinen Mechanismus gibt, sie ohne erneutes Deployment zu steuern.
Dies sind keine Randfälle. Es sind die Bereiche, in denen die meisten CI/CD-Implementierungen Risse bekommen. Die gute Nachricht ist: Ihre Pipeline um Konfiguration, Mobile-Apps und Feature Flags zu erweitern, ist unkompliziert, sobald Sie wissen, worauf Sie achten müssen.
Konfiguration als separater Auslieferungspfad
Die meisten Teams speichern Konfiguration zunächst in Umgebungsvariablen oder Konfigurationsdateien, die neben dem Anwendungscode liegen. Das funktioniert, bis es nicht mehr funktioniert. Sobald Sie einen Wert für eine Umgebung ändern müssen, ohne andere zu beeinflussen, wird klar, dass Konfiguration und Code unterschiedliche Lebenszyklusanforderungen haben.
Konfigurationsänderungen sollten keinen Build erfordern. Sie sollten nicht das Ausführen der gesamten Testsuite erfordern. Sie sollten kein Deployment erfordern, das die Anwendung neu startet. Ein Datenbank-Verbindungsstring, ein API-Schlüssel oder ein Feature-Toggle-Wert ist kein Code. Ihn wie Code zu behandeln, fügt unnötige Reibung hinzu.
Die Lösung besteht darin, Konfiguration vom Code zu trennen und ihr eine eigene Pipeline zu geben. Diese Pipeline ist einfacher als die für Anwendungscode:
Das folgende Diagramm zeigt, wie die Haupt-Pipeline in drei verschiedene Pfade verzweigt, jeder mit seinem eigenen Lebenszyklus.
Eine Feature-Flag-Konfigurationsdatei könnte beispielsweise so aussehen:
{
"new_checkout": {
"enabled": true,
"rollout_percentage": 10,
"description": "Schrittweises Ausrollen des neu gestalteten Checkout-Ablaufs"
},
"dark_mode": {
"enabled": false,
"rollout_percentage": 0,
"description": "Dark-Mode-Umschalter für alle Benutzer"
},
"search_autocomplete": {
"enabled": true,
"rollout_percentage": 100,
"description": "Autovervollständigung in der Suchleiste, vollständig ausgerollt"
}
}
Die Anwendung liest diese Datei beim Start und prüft regelmäßig auf Aktualisierungen. Die Änderung von rollout_percentage von 10 auf 50 erfordert keinen Build oder Deployment – die Anwendung übernimmt den neuen Wert dynamisch.
- Eine Änderung eines Konfigurationswerts wird in ein Repository eingespielt
- Die Änderung durchläuft denselben Überprüfungsprozess wie Code-Änderungen
- Nach der Freigabe wird die Konfiguration auf die Zielumgebung angewendet
- Die Anwendung übernimmt den neuen Wert ohne Neustart
Der entscheidende Unterschied ist, dass die Konfigurations-Pipeline die Build- und Test-Phasen überspringt. Es gibt nichts zu kompilieren oder zu testen. Wichtig ist, dass die Konfiguration den richtigen Server erreicht und die Anwendung sie dynamisch neu laden kann.
Dieser Ansatz erleichtert auch die Überwachung. Jede Konfigurationsänderung wird in der Versionskontrolle nachverfolgt, von einem Kollegen überprüft und über eine Pipeline angewendet. Kein SSH-Zugriff mehr auf einen Server, um einen Wert zu ändern und zu hoffen, dass es niemand bemerkt.
Mobile-Pipelines haben andere Einschränkungen
Mobile-Anwendungen sehen aus wie jedes andere Softwareprojekt – bis Sie versuchen, sie auszuliefern. Der Build-Prozess erzeugt eine Installationsdatei, die digital signiert werden muss. Die Verteilung erfolgt über App-Stores mit eigenen Überprüfungsprozessen. Und sobald eine Version bei den Benutzern ist, können Sie sie nicht zwingen, zu aktualisieren.
Diese Einschränkungen ändern, wie Sie die Pipeline gestalten. Die Build- und Unit-Test-Phasen funktionieren genauso wie bei Backend-Anwendungen. Aber die Deployment-Phase benötigt zwei separate Pfade:
Der erste Pfad ist für die interne Verteilung. Bevor Sie einen Build an den App-Store senden, muss Ihr Team ihn auf echten Geräten testen. Plattformen wie Firebase App Distribution für Android und TestFlight für iOS ermöglichen es Ihnen, Builds an QA-Teams und Beta-Tester zu verteilen, ohne den App-Store-Überprüfungsprozess zu durchlaufen. Ihre Pipeline sollte Builds automatisch auf diese Plattformen hochladen, sobald eine neue Version zum Testen bereit ist.
Der zweite Pfad ist für die Produktionsveröffentlichung. Hier übermittelt die Pipeline den signierten Build an den Google Play Store oder Apple App Store. Die Pipeline kann nicht steuern, wie lange die Überprüfung dauert, aber sie kann den Status verfolgen. Wenn die Überprüfung genehmigt ist, kann die Pipeline die eigentliche Veröffentlichung für die Benutzer auslösen.
Risikogates für Mobile-Pipelines müssen mobile-spezifische Prüfungen enthalten. Ablaufdaten von Zertifikaten, Gültigkeit von Signaturschlüsseln und Versionsnummern-Inkremente sollten automatisch überprüft werden. Ein Build mit einem abgelaufenen Zertifikat wird vom App-Store abgelehnt, und das erst nach der Wartezeit auf die Überprüfung herauszufinden, ist schmerzhaft.
Feature Flags ermöglichen schrittweise Ausrollungen
Feature Flags sind ein Mechanismus, mit dem Sie Funktionen ein- oder ausschalten können, ohne neuen Code auszuliefern. Sie lösen ein häufiges Problem: Eine Funktion ist fertig, aber Sie sind nicht sicher, ob sie für alle Benutzer bereit ist. Vielleicht braucht sie mehr Tests. Vielleicht möchten Sie sie zuerst nur für einen kleinen Prozentsatz der Benutzer ausrollen. Vielleicht möchten Sie die Möglichkeit haben, sie schnell zu deaktivieren, wenn etwas schiefgeht.
Ohne Feature Flags sind Ihre Optionen begrenzt. Sie können das Deployment verzögern, bis Sie sicher sind, was die Auslieferung verlangsamt. Oder Sie deployen und hoffen auf das Beste, was das Risiko erhöht. Feature Flags geben Ihnen eine dritte Option: Deployen Sie die Funktion im deaktivierten Zustand und aktivieren Sie sie dann schrittweise.
Das Hinzufügen von Feature Flags zu Ihrer Pipeline erfordert zwei Änderungen:
Erstens muss die Pipeline überprüfen, ob der Code in beiden Zuständen korrekt funktioniert. Wenn eine Funktion in ein Flag eingeschlossen ist, sollten die Tests mit aktiviertem und deaktiviertem Flag ausgeführt werden. Dies erfasst Probleme, bei denen die Feature-Flag-Logik selbst Fehler enthält oder der deaktivierte Zustand die bestehende Funktionalität beeinträchtigt.
Zweitens sollte die Pipeline Ihnen helfen, Flags zu bereinigen, die nicht mehr benötigt werden. Feature Flags, die für immer im Code bleiben, werden zu technischen Schulden. Sie erhöhen die Komplexität, erschweren das Lesen des Codes und erhöhen das Risiko von Fehlern. Eine gute Praxis ist es, eine Pipeline-Stufe hinzuzufügen, die nach Flags sucht, die für einen bestimmten Zeitraum vollständig an alle Benutzer ausgerollt wurden, und dann automatisch eine Aufgabe zu deren Entfernung erstellt.
Praktische Checkliste zur Erweiterung Ihrer Pipeline
Bevor Sie mit der Implementierung dieser Änderungen beginnen, gehen Sie diese Checkliste durch, um zu identifizieren, was Aufmerksamkeit benötigt:
- Können Sie einen Konfigurationswert für eine Umgebung ändern, ohne die Anwendung neu zu deployen?
- Wird jede Konfigurationsänderung in der Versionskontrolle nachverfolgt und vor der Anwendung überprüft?
- Verteilt Ihre Mobile-Pipeline automatisch Builds an interne Tester?
- Überprüft Ihre Mobile-Pipeline den Ablauf von Zertifikaten und die Gültigkeit von Signaturschlüsseln?
- Werden Feature Flags sowohl im aktivierten als auch im deaktivierten Zustand getestet?
- Haben Sie einen Prozess zum Entfernen nicht mehr benötigter Feature Flags?
Wenn Sie eine dieser Fragen mit Nein beantwortet haben, haben Sie einen klaren nächsten Schritt.
Das Fazit
CI/CD ist nicht abgeschlossen, wenn Ihr Anwendungscode reibungslos deployed wird. Es ist abgeschlossen, wenn jede Änderung, die das Verhalten Ihrer Software beeinflusst – ob Code, Konfiguration oder ein Feature-Toggle – einen kontrollierten, automatisierten und überprüfbaren Prozess durchläuft. Konfigurations-Pipelines beseitigen die Reibung umgebungsspezifischer Änderungen. Mobile-Pipelines handhaben die besonderen Einschränkungen der App-Store-Verteilung. Feature Flags geben Ihnen die Möglichkeit, Risiken zu kontrollieren, ohne die Auslieferung zu verlangsamen.
Beginnen Sie mit dem Bereich, der Ihrem Team heute die meisten Schmerzen bereitet. Für die meisten Teams ist das das Konfigurationsmanagement. Sobald das funktioniert, gehen Sie zu Mobile oder Feature Flags über, je nachdem, was Ihr Team ausliefert. Das Ziel ist nicht, am ersten Tag die perfekte Pipeline zu bauen. Das Ziel ist sicherzustellen, dass nichts durchs Raster fällt.