Continuous Integration, Delivery und Deployment im Vergleich

Wenn Sie sich schon eine Weile mit Softwareentwicklung beschäftigen, haben Sie den Begriff CI/CD höchstwahrscheinlich schon gehört.

Continuous Integration, Continuous Delivery und Continuous Deployment sind Methoden, mit denen der Software-Releaseprozess beschleunigt werden soll, indem Feedback-Schleifen verkürzt und wiederholungsintensive Aufgaben automatisiert werden. Diese Methoden spielen eine Schlüsselrolle dabei, das Agile-Prinzip – Bereitstellung von wertvoller, funktionierender Software in kurzen Abständen – in die Wirklichkeit umzusetzen.

Für Entwicklerteams, die ihren Rhythmus gefunden und CI/CD-Tools und Prozesse für einen regelmäßigen Release-Zyklus eingerichtet haben, ist eine gut funktionierende CI/CD-Pipeline eine Quelle des Stolzes – ein Zeichen dafür, dass das Team es versteht, seine Werkzeuge so einzusetzen, dass die eigene Umgebung und das erstellte Endprodukt besser werden.

Für jemanden, der die Methode gerade erst kennengelernt hat, mag es hingegen schwierig oder unmöglich erscheinen, den eigenen Build-, Test- und Bereitstellungsprozess in ein automatisiertes System umzuwandeln. Aber das muss nicht zwingend so bleiben. Das Schöne am Aufbau einer CI/CD-Pipeline ist, dass sie sich problemlos in separate Phasen unterteilen lässt, wobei jede Phase auf der vorhergehenden aufbaut. Schauen wir uns diese Phasen nacheinander an.

Schauen wir uns an, was CI und CD ist und was die Hauptmerkmale der beiden sind.

Continuous Integration, Delivery und Deployment im Vergleich

Was ist Continuous Integration?

Bei Continuous Integration geht es darum, die Schritte, die traditionell während der sogenannten „Integration“ ausgeführt wurden, im Verlauf des Entwicklungsprozesses häufig und in kleinen Stücken auszuführen, anstatt zu warten, bis der Code fertiggestellt ist, um dann alles zusammenzuführen und zu testen.

Angenommen, mehrere Personen arbeiten an einem Softwareprodukt, was die Regel für die meisten kommerziellen und Open-Source-Projekte sein dürfte: Irgendwann müssen die separaten Teile, an denen die einzelnen Mitwirkenden gearbeitet haben, kombiniert werden, um zu überprüfen, ob das Endprodukt wie beabsichtigt funktioniert. Bei Continuous Integration passiert dies mindestens einmal am Tag oder noch häufiger.

Die Begründung ist einfach. Wenn wir die Integration hinausschieben, bis der gesamte Code fertig ist, ist die Wahrscheinlichkeit hoch, dass wir einige Zeit damit verbringen müssen, Teile des Codes zu entfernen und neu zu schreiben, um überhaupt den Build zum Laufen zu bekommen – vom Erreichen der angepeilten Funktionalität gar nicht zu reden. Software ist komplex. Selbst wenn vorab ein detailliertes Design erstellt wird, ist es unglaublich schwierig, Probleme zu vermeiden und genau vorherzusagen, wie die Logik interagieren wird. Je größer der Umfang des Codes ist, desto größer ist die Komplexität und desto mehr muss rückgebaut werden, wenn etwas nicht funktioniert.

Durch Continuous Integration steuern die einzelnen Mitwirkenden ihre Änderungen regelmäßig zum Gesamtsystem bei, indem sie mindestens einmal am Tag einen Commit in die Quellcodeverwaltung durchführen und dabei überprüfen, ob der Build durchläuft und die Tests besteht. Dadurch müssen bei einem Fehler weitaus weniger Änderungen analysiert werden, um die Ursache zu finden. Außerdem sind bei zeitnahem Feedback Probleme leichter zu beheben, da den Entwickler*innen der Kontext ihrer Aktivitäten noch präsent ist.

Zu einem guten CI-Prozess gehören einige wesentliche Zutaten:

Quellcodeverwaltung nutzen

Ein System zur Quellcodeverwaltung (auch bekannt als Versionsverwaltung) ist unbedingt erforderlich. Wenn Sie noch keines haben oder nur ein Teil Ihres Codes unter Quellcodeverwaltung gestellt ist, sollten Sie in einem ersten Schritt dafür sorgen, dass das System von allen Mitwirkenden und für den gesamten Code verwendet wird.

Früh und häufig Commits durchführen

Sobald eine Quellcodeverwaltung eingerichtet ist, sollte sich das gesamte Team angewöhnen, früh und häufig Commits durchzuführen. Eine Einflussgröße ist dabei der Umfang der Aufgaben. Wenn Sie jede Arbeit in kleinere Häppchen aufteilen, wird es leichter, Änderungen lokal umzusetzen und zu testen, um die Commitreife zu erreichen.

Nach jedem Commit einen Build erstellen

Das regelmäßige Teilen der Codeänderungen mit allen Projektmitwirkenden ist nur der Anfang. Der nächste Schritt besteht darin, zu überprüfen, ob mit den neuesten Änderungen ein Build erstellt werden kann. Dies könnte zwar manuell erfolgen, es ist jedoch viel einfacher und effizienter, den Build automatisch auszulösen. An dieser Stelle kommen CI-Server ins Spiel.

Tests automatisieren

Ein erfolgreicher Build ist ein gutes Zeichen. Noch mehr Vertrauen in die Änderungen entsteht jedoch, wenn Sie auch einige Tests durchführen. Auch hier gilt: Es ist viel einfacher und effizienter, Tests automatisch statt manuell auszuführen. Auf den ersten Blick erscheint das Schreiben automatisierter Tests als arbeitsintensiv, aber sie machen sich schnell bezahlt, wenn sie bei jedem Build ausgeführt werden und schnelles Feedback bereitstellen.

Feedback beachten

Builds und Tests zu automatisieren lohnt sich nur, wenn Sie mit den erhaltenen Informationen auch etwas anfangen. CI-Tools bieten eine Reihe von Feedback-Mechanismen, von Dashboards und Radiatoren bis hin zur Integration in Instant-Messaging-Plattformen.

DevOps-Kultur aufbauen

Um die Vorteile von Continuous Integration umfassend nutzen zu können, müssen Sie eine Teamkultur schaffen, in der die Verantwortung für die Korrektur fehlerhafter Builds oder fehlgeschlagener Tests auf alle Schultern verteilt ist. Die Schuld bei der Person zu suchen, die den letzten Commit durchgeführt hat, ist kontraproduktiv, denn es kann das Team davon abhalten, frühzeitig und oft Commits vorzunehmen – obwohl dies ja im Interesse aller liegt.

Wenn Sie all diese Zutaten kombinieren, erhalten Sie schnelles und regelmäßiges Feedback zu Ihrem Code. Durch die Gewissheit, dass Codeänderungen – ganz gleich, ob es sich um eine Fehlerkorrektur, eine Refaktorierung oder einen Teil eines neuen Features handelt – zumindest zu einem sauberen Build führen, der die Tests besteht, kann das Team vermeiden, neue Arbeitsschritte auf einem schlechten Fundament aufzubauen – mit dem unvermeidlichen Überarbeitungsaufwand, der daraus folgt. Die Implementierung von Continuous Integration ist für sich genommen bereits ein großer Schritt, der die Bereitstellung funktionsfähiger Software beschleunigt.

Einführung in Continuous Delivery

Continuous Delivery baut auf den Grundlagen auf, die wir mit Continuous Integration in Sachen Build- und Testautomatisierung gelegt haben.

Bei Continuous Delivery ersetzen wir die manuellen Schritte, mit denen wir ein Build unserer Software für die Produktion freigeben, durch einen automatisierten Prozess.

Früher erfolgte oft eine Übergabe von der Entwicklung an die Testabteilung und von dort an das Release-Management. Durch Continuous Delivery ist das gesamte Team (mit Mitgliedern aus verschiedenen Disziplinen) für den kompletten Prozess verantwortlich: Build, Test und Release. Dies bringt mehrere Vorteile mit sich:

  • Durch die Vermeidung der traditionellen Silos hat das Entwicklungsteam einen besseren Einblick in die geschäftlichen und operativen Anforderungen, die zur Bereitstellung des Produkts an die Benutzer*innen erfüllt werden müssen.
  • Dies eröffnet wiederum die Möglichkeit, Methoden aus der Softwareentwicklung in einen normalerweise manuellen und oft recht langwierigen Prozess einzubringen.
  • Durch Automatisierung der Schritte zur Bereitstellung eines Produkts wird nicht nur der Prozess beschleunigt, sondern auch das Fehlerrisiko verringert, und das Produkt wird stabiler und zuverlässiger.

Die genauen Schritte für die Bereitstellung von Software – und somit die erforderlichen Phasen in der Delivery-Pipeline – variieren je nach Geschäfts- und Nutzungsanforderungen. Normalerweise jedoch durchläuft eine Software vor dem Release mindestens eine Vorproduktionsumgebung.

Diese Vorproduktionsumgebungen können unterschiedlich gestaltet sein, zum Beispiel als Testumgebungen mit zusätzlichen Testebenen für Sicherheits-, Last- oder Leistungstests, als Sandbox-Umgebungen, in denen sich Support- und Vertriebsteams mit neuen Funktionen vertraut machen, oder als Akzeptanztestumgebungen, in denen QS- und Produktexperten überprüfen, ob die Änderungen nach Plan funktionieren.

Bei Continuous Delivery wird jeder erfolgreiche Build automatisch in jeder Vorproduktionsumgebung bereitgestellt, wobei das Vertrauen in die Qualität mit jeder Phase zunimmt.

Um dieses lohnende Ziel zu erreichen, sind jedoch einige Investitionen erforderlich:

Builds nur einmal erstellen

Nur wenn das Build-Artefakt in jeder Phase der Pipeline identisch bleibt, können Sie sich sicher sein, dass alle vorherigen Testphasen tatsächlich bestanden wurden.

Konfiguration in der Quellcodeverwaltung speichern

Wenn alle Ihre Konfigurationsdateien in der Quellcodeverwaltung gespeichert sind, können Sie sicherstellen, dass die Bereitstellungen konsistent und reproduzierbar sind.

Jedes Deployment automatisieren

Die Bereitstellung in jeder Umgebung sollte per Skript erfolgen, damit sie automatisch und jedes Mal auf genau identische Weise erfolgen kann. Auch das Release in die Produktionsumgebung sollte aus demselben Grund geskriptet werden – allerdings erfolgt bei Continuous Delivery dieser letzte Schritt nicht automatisch.

Umgebungen bereinigen

Für ein vollständig konsistentes Vorgehen sollten die Umgebungen für jede neue Bereitstellung auf die gleichen Ausgangsbedingungen zurückgesetzt werden. Dank Containern ist dies heute viel einfacher umzusetzen – sowohl in der lokalen Infrastruktur als auch in der Cloud.

Separate Umgebungen

Um die Bereitstellung desselben Artefakts in den einzelnen Umgebungen zu automatisieren, muss eine klare Trennung zwischen der Anwendung und den umgebungsspezifischen Variablen oder Parametern bestehen.

Pipeline pflegen

Wie bei Continuous Integration lohnt sich eine automatisierte Delivery-Pipeline nur dann, wenn sie entsprechend gewartet wird. Bei CI/CD ist die Teamkultur genauso wichtig wie die Prozesse und Tools. Um die Pipeline effektiv nutzen zu können, muss sich Ihr Team um die Wartung kümmern und alle auftretenden Probleme beheben, unabhängig davon, ob sie auf einen Fehler im Code oder auf ein Problem bei der Deployment- oder Testautomatisierung zurückzuführen sind.

Bei Continuous Delivery übernehmen alle Teammitglieder gemeinsam die Verantwortung für die Bereitstellung der Software. Im Gegenzug erhalten sie zeitnahes Feedback während des gesamten Prozesses. Wie bei Continuous Integration kann der praktische Ablauf mit der Zeit ausgebaut und verbessert werden.

Was ist Continuous Deployment?

Continuous Deployment bringt die Methoden von Continuous Integration und Continuous Delivery zu ihrem logischen Ende:

Wenn ein Build alle vorangehenden Phasen der Pipeline erfolgreich durchläuft, wird er automatisch in die Produktion übernommen. Dies bedeutet, dass jede Änderung sofort den Weg zu Ihrer Benutzergemeinde findet, sobald die Software alle Tests bestanden hat. Durch Continuous Deployment wird die Feedback-Schleife zwischen Codeänderung und Produktionseinsatz verkürzt, sodass Ihr Team einen frühzeitigen Einblick in das Verhalten der Änderungen in der realen Welt erhält, ohne Kompromisse bei der Qualität eingehen zu müssen.

Auch wenn die automatisierte Bereitstellung von Software für die Produktion nicht für jedes Produkt und jede Organisation geeignet ist, lohnt es sich, die dazu erforderlichen Schritte zu betrachten, da jedes einzelne Element bereits für sich genommen wertvoll ist:

Vertrauenswürdige Tests

Die automatische Bereitstellung in die Produktionsumgebung erfordert ein hohes Maß an Vertrauen in die Pipeline, insbesondere in die automatisierten Tests. Entscheidend ist dabei eine robuste Testkultur: Ihr Team muss in Test-Coverage und -Performance investieren, und die Fehlerkorrektur in Builds und der Pipeline muss vor neuen Features Priorität haben.

Produktionsumgebung überwachen

Selbst nach der Umsetzung aller genannten Maßnahmen kann Continuous Deployment zu riskant erscheinen. Was passiert, wenn ein Fehler beim Testen unentdeckt bleibt und nur in der Produktion zum Vorschein kommt? Zeit, Geld und der Ruf des Unternehmens stehen potenziell auf dem Spiel. Zwar kann das gleiche Problem auch bei manuellem Deployment auftreten, aber ein Showstopper, der automatisch „vom System“ freigegeben wurde, kann tatsächlich im Nu das Vertrauen Ihrer Stakeholder erschüttern. Hier macht es einen großen Unterschied, ob man proaktiv nach Anzeichen von Problemen Ausschau hält oder passiv auf Benutzerbeschwerden wartet. Indem Sie statistische Werte auf Normabweichungen überwachen, insbesondere unmittelbar nach einem Release, können Sie Fehler entdecken, noch bevor sie sichtbare Probleme für Ihre Nutzergemeinde verursachen.

Bewusst veröffentlichen

Ein häufiger Einwand derjenigen, die noch keine Erfahrungen mit Continuous Deployment gemacht haben, lautet folgendermaßen: Wenn man frühzeitig und häufig Commits durchführt und alles Mögliche ohne manuelle Kontrolle absegnet, werden der Benutzergemeinde unfertige oder halbfertige Features vorgesetzt, mit denen sich nicht arbeiten lässt. Anstatt auf Branches zurückzugreifen und auf die Vorteile der Continuous Integration zu verzichten, können Sie Feature-Flags verwenden. Ihr Entwicklungsteam kann dann beim Schreiben des Codes steuern, welche Features für Benutzer*innen sichtbar sein sollen und welche nicht.

Pipeline optimieren

Wenn in der Produktion etwas schiefgeht, sollte eine schnelle Reaktion möglich sein. Manchmal lässt sich ein Rollback zur Vorversion durchführen. Oft liegen die Dinge jedoch komplizierter – Datenbankmigrationen und Korrekturen für bekannte Probleme lassen oft nur den Weg nach vorn frei, sodass die einzige Möglichkeit darin besteht, den Fehler durch einen Fix zu beheben. Schritte in der Pipeline zu überspringen lohnt sich nicht, da hierbei Fehler auftreten können, die bei einer ordnungsgemäßen Ausführung aller Tests entdeckt worden wären. Stattdessen empfiehlt es sich, in die Optimierung der Pipeline zu investieren, von der Build-Geschwindigkeit bis hin zur Testperformance. Dadurch gewinnen Sie nicht nur die Fähigkeit, Änderungen bei Bedarf schnell bereitzustellen – Sie verkürzen auch die Feedback-Schleifen entlang der gesamten Prozesskette.

Rollout kontrollieren

Obwohl Continuous Deployment die automatische Freigabe bedeutet, wenn alle vorherigen Phasen erfolgreich durchlaufen wurden, bedeutet dies nicht, dass man jede Kontrolle aus der Hand geben muss. Es gibt verschiedene Deployment-Verfahren, mit denen das Risiko minimiert und der Rollout gesteuert werden kann. Mit Canary Releases können Sie neue Releases zunächst an einer kleinen Benutzergruppe testen, und mit Blue-Green-Deployments lässt sich der Umstieg auf eine neue Version managen.

Continuous Integration, Continuous Delivery und Continuous Deployment dienen allesamt dem Ziel, Ihrer Nutzergemeinde in kurzen Abständen ein nützliches, funktionierendes Softwareprodukt bereitzustellen. Das Prinzip „wenig aber oft“ macht den Integrations- und Releaseprozess übersichtlicher und bietet dem Team zugleich die Möglichkeit, die Schritte regelmäßig zu üben und zu verbessern.

Durch Automatisierung wird der Prozess wiederum nicht nur schneller, sondern auch zuverlässiger. Jeder Schritt in der Pipeline baut auf den vorherigen auf, und Sie können selbst festlegen, wie viel Sie zu einem bestimmten Zeitpunkt investieren möchten – Sie können später jederzeit zurückkehren, um auf das Vorhandene aufzubauen.

Hauptunterschiede zwischen CI und CD

Continuous Integration, Delivery und Deployment im Vergleich

Continuous Integration, Delivery und Deployment sind aufeinander folgende Phasen des Softwarebereitstellungsprozesses. Sie helfen Teams, Software schneller zu veröffentlichen, die Feedback-Schleife zu verkürzen und wiederholungsintensive Tätigkeiten zu automatisieren. Es ist nicht weniger wichtig, die wichtigsten Unterschiede zwischen Continuous Integration, Delivery und Deployment zu erkennen, als zu verstehen, wie diese drei Schritte zusammenwirken, um den Benutzer*innen Software auf zuverlässige und stabile Weise zu liefern.

Bei der kontinuierlichen Integration werden alle neuen Codeänderungen in den Hauptbranch integriert. Continuous Delivery automatisiert manuelle Aufgaben, die zum Erstellen und Testen von Software erforderlich sind (z. B. durch Automatisierung von Tests). Continuous Deployment ist die logische Fortsetzung der Automatisierung von Build- und Testschritten. In diesem Schritt wird die Software automatisch bereitgestellt, sobald sie alle erforderlichen Prüfpunkte durchlaufen hat.

Im Allgemeinen geht es nicht um die Frage CI und CD, sondern vielmehr darum, wie all diese Komponenten zusammenwirken, um eine stabile, zuverlässige Pipeline zu schaffen.