Stell dir zwei Entwicklungsteams vor.
Das erste bereitet eine neue Version der Anwendung vor.
Der Entwickler beendet die Aufgabe. Jemand prüft den Code. Danach müssen Tests ausgeführt werden. Jemand bereitet das Paket vor. Jemand anderes meldet sich auf dem Server an. Anschließend sind einige manuelle Schritte nötig, die Konfiguration muss geprüft und das System nach dem Deployment beobachtet werden. Wenn alles gut geht, ist die neue Version verfügbar.
Das zweite Team arbeitet anders.
Der Code gelangt ins Repository. Automatisch laufen Tests, Qualitätsanalysen und Sicherheitsprüfungen an. Das System baut die Anwendungsversion, deployt sie in die Testumgebung, führt weitere Prüfungen durch und kann sie nach Erfüllung bestimmter Bedingungen in Produktion deployen. Wenn etwas schiefgeht, wird das Deployment gestoppt oder das System kann zur vorherigen Version zurückkehren.
Beide Teams entwickeln Software.
Aber nur eines von ihnen hat einen wiederholbaren Software-Lieferprozess aufgebaut.
Und genau darum geht es bei CI/CD.
"Funktioniert in Produktion" ist noch kein ausgereifter Prozess
Viele Unternehmen messen Erfolg an einer sehr einfachen Kennzahl: Die Anwendung funktioniert.
Das ist natürlich eine Grundvoraussetzung.
Aber mit dem Wachstum des Systems tauchen weitere Fragen auf:
- Wie schnell können wir einen Fix deployen?
- Wie oft können wir neue Funktionen veröffentlichen?
- Wie viele manuelle Schritte führen wir bei jedem Deployment aus?
- Kann jeder Entwickler den Deployment-Prozess nach denselben Regeln ausführen?
- Wissen wir, welche Version gerade läuft?
- Können wir zur vorherigen Version zurückkehren?
- Prüfen wir nach dem Deployment automatisch, ob das System korrekt funktioniert?
- Haben wir Monitoring?
- Wissen wir, dass ein Deployment ein Problem verursacht hat, bevor der Kunde es meldet?
Das sind Fragen des Software Delivery und nicht nur der eigentlichen Programmierung.
CI und CD - zwei Elemente eines Prozesses
CI, also Continuous Integration, bedeutet die kontinuierliche Integration von Änderungen.
In der Praxis geht es darum, dass Änderungen häufig in das gemeinsame Repository gelangen und automatisch überprüft werden.
Eine typische Pipeline kann unter anderem Folgendes ausführen:
-
Kompilieren oder Bauen der Anwendung,
-
Unit-Tests,
-
Integrationstests,
-
Linting,
-
statische Codeanalyse,
-
Abhängigkeits-Scanning,
-
Sicherheitsprüfungen,
-
Erstellen von Deployment-Artefakten.
So kann ein Problem entdeckt werden, bevor der Code in Produktion gelangt.
CD, also Continuous Delivery oder Continuous Deployment, betrifft die nächste Stufe - die Auslieferung von Änderungen.
Je nach gewähltem Modell kann das System eine fertige Version für das Deployment vorbereiten oder sie nach bestandenen Prüfungen automatisch deployen.
Diese Unterscheidung ist wichtig.
Continuous Delivery muss nicht bedeuten, dass jede Änderung automatisch in Produktion deployt wird.
Es kann einfach bedeuten, dass jede Version wiederholbar für das Deployment vorbereitet wird.
Warum werden manuelle Deployments zum Problem?
Ein manuelles Deployment muss nicht schlecht sein.
In einem kleinen Projekt kann es völlig ausreichend sein.
Das Problem beginnt dann, wenn der Prozess mit der Anwendung mitwächst.
Zuerst haben wir eine Person, die weiß, wie das System deployt wird. Dann kommt ein zweiter Server hinzu. Später die Testumgebung. Dann Datenbank, Cache, Warteschlangen, Storage, mehrere Services und externe APIs. Dazu kommen unterschiedliche Konfigurationen für Development, Tests und Produktion.
Nach ein paar Jahren kann der Prozess ungefähr so aussehen:
"Zuerst X ausführen, dann den Parameter Y ändern, anschließend den Dienst Z neu starten, aber vorher ein Backup der Datenbank machen. Und wenn ein Fehler auftritt, ruf die Person an, die das letztes Mal deployed hat."
Das ist kein Prozess mehr. Das ist Wissen, das im Kopf eines Menschen steckt. Und genau dann steigt das Risiko.
Automatisierung dient nicht nur dem Komfort der Entwickler
Oft wird CI/CD als Werkzeug dargestellt, das den Komfort der Entwickler erhöht. Das stimmt, aber es ist nur ein Teil des Bildes.
Die Automatisierung des Deliveries erhöht vor allem die Wiederholbarkeit des Prozesses.
Wenn ein Mensch das Deployment ausführt, besteht die Möglichkeit, dass er jedes Mal etwas anders macht.
Wenn es die Pipeline macht, kann man eine exakte Abfolge von Schritten definieren.
Dieselbe Version.
Dieselben Tests.
Dieselben Prüfungen.
Dieselben Regeln.
Das ist besonders wichtig in Projekten, die von mehreren Personen oder mehreren Teams entwickelt werden.
Tests vor dem Deployment sind wichtiger als die Geschwindigkeit des Deployments
Automatisierung ohne Tests kann lediglich dazu führen, dass Fehler schneller auftreten.
Deshalb sollte eine gut entworfene Pipeline nicht nur ein Mechanismus sein: "Code → Produktion".
Sie sollte ein Qualitätssicherungssystem sein.
Je nach Projekt können darin enthalten sein:
- Unit-Tests - prüfen einzelne Elemente der Logik.
- Integrationstests - prüfen das Zusammenspiel von Komponenten.
- End-to-End-Tests - simulieren reale Nutzerszenarien.
- Sicherheitstests - prüfen unter anderem Abhängigkeiten und bekannte Schwachstellen.
- Performance-Tests - erforderlich dort, wo die Bewältigung einer bestimmten Last wichtig ist.
Nicht jede Anwendung braucht all diese Ebenen in gleichem Umfang.
Und das ist wichtig.
CI/CD bedeutet nicht, möglichst viele Tools in die Pipeline zu werfen.
Es geht darum, die Kontrollen dem Risiko des konkreten Systems anzupassen.
Was passiert, wenn ein Test fehlschlägt?
Das ist eine der wichtigsten Fragen im gesamten Prozess.
Eine ausgereifte Pipeline sollte klar definierte Regeln haben.
Wenn ein kritischer Test fehlschlägt, sollte die Version nicht als deploymentbereit gelten.
Wenn ein Sicherheitsscan ein bestimmtes Risikoniveau erkennt, kann die Pipeline den Prozess stoppen.
Wenn der Build fehlschlägt, gibt es nichts zu deployen.
Das klingt banal. Aber genau solche automatischen "Gates" sorgen dafür, dass Qualität nicht allein von der Erinnerung und Genauigkeit des Menschen abhängt.
Und was, wenn das Deployment doch fehlschlägt?
Selbst der beste Prozess eliminiert nicht alle Fehler. Deshalb ist das zweite Element eines ausgereiften Deliveries die Möglichkeit eines kontrollierten Rollbacks der Änderung.
Rollback kann die Rückkehr zum vorherigen Artefakt, Container-Image oder zur vorherigen Anwendungsversion bedeuten. Aber hier taucht ein wichtiges Problem auf. Ein Code-Rollback bedeutet nicht immer ein Daten-Rollback.
Wenn die neue Version die Datenbankstruktur verändert hat, wird die Situation komplizierter.
Daher sollten Datenbankmigrationen so entworfen werden, dass der gesamte Prozess möglichst sicher und reversibel ist oder zumindest mit der vorherigen Version der Anwendung kompatibel bleibt.
Das ist eines der Beispiele, die zeigen, dass professionelles CI/CD ein architektonisches Problem ist und nicht nur eine Konfiguration eines Tools.
Blue-Green-, Canary- und andere Bereitstellungsstrategien
In anspruchsvolleren Systemen muss nicht sofort der gesamte Traffic auf die neue Version umgeschaltet werden. Es können verschiedene Deployment-Strategien eingesetzt werden.
Blue-Green-Deployment
Es laufen zwei Versionen der Umgebung.
Eine bedient den Traffic, die andere wird auf die Übernahme des Traffics vorbereitet.
Nach erfolgreicher Verifizierung erfolgt die Umschaltung.
Der Vorteil ist die Möglichkeit, schnell zur vorherigen Umgebung zurückzukehren.
Ein Nachteil kann der höhere Infrastrukturverbrauch sein.
Canary-Deployment
Die neue Version gelangt zunächst zu einem kleinen Teil der Nutzer oder des Traffics.
Wenn das Monitoring keine Probleme zeigt, kann der Rollout-Bereich schrittweise erweitert werden.
Das begrenzt die potenzielle Reichweite eines Fehlers.
Es erfordert jedoch eine geeignete Infrastruktur, Monitoring und eine Methode zur Traffic-Verwaltung.
Feature Flags
Eine Funktion kann im System bereitgestellt werden, bleibt aber für die Nutzer deaktiviert.
Dadurch werden das Bereitstellen des Codes und das Aktivieren der Funktion zu zwei separaten Prozessen.
Das gibt mehr Kontrolle, besonders bei großen Änderungen.
Das bedeutet jedoch nicht, dass Feature Flags für jedes Projekt die richtige Lösung sind. Ein Übermaß davon kann ebenfalls die Systemkomplexität erhöhen.
Monitoring nach dem Deployment
Man kann alle Tests durchführen. Man kann eine großartige Pipeline haben. Man kann eine neue Version ohne jeden Fehler bereitstellen. Und ein paar Minuten später kann sich die Anwendung unter echter Last anders verhalten.
Deshalb sollte der Prozess nicht beim Deployment enden. Es braucht Observability, also die Möglichkeit zu verstehen, was im Inneren des laufenden Systems passiert.
Je nach Architektur umfasst sie unter anderem:
-
Logs,
-
Metriken,
-
Tracing,
-
Infrastruktur-Monitoring,
-
Anwendungs-Monitoring,
-
Alerts,
-
Fehlerinformationen,
-
Geschäftskennzahlen.
Es geht nicht darum, alles zu sammeln. Es geht darum, wichtige Fragen auf Basis von Daten beantworten zu können.
Läuft die Anwendung?
Läuft sie langsamer als zuvor?
Ist die Anzahl der Fehler gestiegen?
Welcher Dienst verursacht das Problem?
Betrifft das Problem alle Nutzer oder nur einen Teil?
100 Deployments pro Tag sind nicht immer das Ziel
Der Titel dieses Artikels spricht von 100 Deployments pro Tag, aber es geht nicht darum, diese Zahl als Ziel festzulegen.
In einem internen System, das einmal im Monat aktualisiert wird, macht es keinen Sinn, künstlich auf Hunderte von Deployments hinzuarbeiten. In einem sehr intensiv entwickelten System kann eine solche Frequenz hingegen technisch möglich sein.
Entscheidend ist die Fähigkeit, Änderungen sicher auszuliefern, und nicht die reine Anzahl der Deployments. Das ist ein fundamentaler Unterschied.
Die Reife des Prozesses misst man nicht daran, wie oft wir deployen, sondern daran, wie vorhersehbar und sicher wir das tun können.
Wann kann CI/CD ein Fall von Form über Inhalt sein?
Nicht jede Anwendung braucht eine komplexe Deployment-Infrastruktur.
Wenn wir eine kleine Anwendung, ein kleines Team und nur wenige Deployments pro Jahr haben, kann eine ausgefeilte Pipeline mehr kosten als die Probleme, die sie löst.
Ähnlich ist es bei sehr speziellen Systemen, bei denen das Deployment aus Sicherheits-, Regulierungs- oder Infrastrukturanforderungen manuell kontrolliert werden muss.
Deshalb sollte die Delivery-Architektur aus den Bedürfnissen des Systems hervorgehen. Nicht aus dem Zeitgeist.
Wann bringt Deployment-Automatisierung besonders viel?
Sie ist besonders dann zu erwägen, wenn:
-
das System regelmäßig weiterentwickelt wird,
-
mehrere Personen am Code arbeiten,
-
mehr als eine Umgebung existiert,
-
Deployments häufig sind,
-
manuelle Deployments Fehler erzeugen,
-
das System geschäftskritisch ist,
-
wir ein schnelles Rollback benötigen,
-
die Anwendung viele Komponenten hat,
-
Audits oder eine Änderungshistorie erforderlich sind,
-
die Zeit bis zur Auslieferung einer Funktion geschäftlich relevant ist.
In solchen Fällen kann eine gut entworfene Pipeline eines der wichtigsten Elemente des Softwareentwicklungsprozesses sein.
CI/CD repariert keine schlechte Architektur
Auch das sollte betont werden.
Man kann eine großartige Pipeline für eine schlechte Anwendung bauen.
Schlechten Code automatisch testen.
Eine schlechte Architektur automatisch deployen.
Ein schlecht entworfenes System automatisch skalieren.
Automatisierung ersetzt also weder Architektur noch Tests noch die Kompetenz des Teams.
Sie verstärkt den bestehenden Prozess.
Wenn der Prozess gut ist, hilft sie, ihn zu skalieren.
Wenn der Prozess schlecht ist, kann sie einfach schneller schlechte Dinge ausführen.
Wie sieht ein reifer Prozess aus?
Es gibt keine eine universelle Pipeline.
Aber ein reifer Prozess sollte einige grundlegende Eigenschaften haben.
Wiederholbarkeit - das Deployment erfolgt nach definierten Schritten.
Automatisierung - Maschinen übernehmen möglichst viel der wiederkehrenden Arbeit.
Testbarkeit - Änderungen werden automatisch überprüft.
Sicherheit - der Prozess umfasst geeignete Sicherheitskontrollen.
Observability - nach dem Deployment ist bekannt, was mit dem System passiert.
Reversibilität - es gibt einen geplanten Weg, auf eine fehlgeschlagene Änderung zu reagieren.
Änderungsverfolgung - es ist bekannt, welche Version deployt wurde und woraus sie entstanden ist.
Zugriffskontrolle - nicht jeder kann beliebig alles in Produktion deployen.
Genau aus solchen Elementen entsteht ein professioneller Software-Delivery-Prozess.
Die wichtigste Veränderung beginnt mit einer anderen Frage
Unternehmen fragen oft: „Wie schnell können wir diese Funktion bauen?“
Es lohnt sich, eine zweite Frage hinzuzufügen: „Wie schnell und sicher werden wir in der Lage sein, die nächsten 50 Funktionen auszuliefern?“
Denn ein einzelnes Deployment kann man manuell durchführen. Man kann eine Anwendung sogar über mehrere Jahre hinweg manuell deployen. Aber mit dem Wachstum des Produkts, des Teams, der Nutzerzahl und der Anzahl der Änderungen steigt auch der Preis für diesen Ansatz.
Deshalb sind CI/CD, automatische Tests, Monitoring und kontrollierte Deployments nicht nur Lösungen für große Konzerne.
Sie sind Elemente der Prozessinfrastruktur, die es ermöglichen, Software weiterzuentwickeln, ohne jeder weiteren Änderung unnötiges Risiko hinzuzufügen.
Und genau darum geht es letztlich.
Nicht um 100 Deployments pro Tag.
Nicht um trendige Tools.
Nicht über die komplizierteste Pipeline.
Nur darüber, sagen zu können:
„Wir haben eine Änderung. Wir haben sie geprüft. Wir wissen, was wir ausrollen. Wir wissen, wie wir sie beobachten. Und wir wissen, was wir tun, wenn etwas schiefgeht.“
