CI/CD in der Praxis – Wie wir Continuous Integration und Continuous Delivery erreichen

CI/CD, also Continuous Integration und Continuous Delivery, sind keine brandneuen Konzepte.

Heutzutage gehört es zum Standard-Repertoire der Softwareentwicklung, dass alle Code-Änderungen sauber aufgeschlüsselt via Git organisiert werden. Auch Deployments (Software-Auslieferungen) werden immer mehr automatisiert.

Allerdings ist das noch nicht bei allen Teams und Systemen so. Auch uns wurden diese CI/CD-Pipelines nicht in die Wiege gelegt, wir mussten das alles erst nach und nach entwickeln.

Wir haben an vielen Stelle Automatismen und Prozesse eingebaut, die uns den Alltag als Software-Team einfacher machen. Da geht es zum Beispiel um automatisierte Tests, Deployments und Loadbalancing.

Hier wollen wir dir zeigen, wie wir was handhaben und warum.

Hinweis: Wenn du dich erst mal einlesen willst, wieso man überhaupt auf CI/CD setzen sollte, dann lies dir unseren Blogartikel über die Vorteile einer Deployment-Pipeline durch.

Continuous Integration

Wer Continuous Delivery anstrebt, muss sich zunächst um Continuous Integration kümmern. Denn wer seinen Code nicht kleinschrittig und zentral verwaltet, der kann keine kleinschrittigen Updates ausliefern.

Für Continuous Integration solltest du deinen Code über ein Versionsverwaltungstool (Version Control System, VCS) wie Git verwalten und zudem ein Cloud-Tool wie Bamboo oder Gitlab nutzen. Wir nutzen Bamboo (von Atlassian).

Was heißt das, kleinschrittig zu entwickeln? Das bedeutet, keine großen Software-Module auf einen Schlag (in einem Branch) zu programmieren. Stattdessen arbeitest du inkrementell und teilst das große neue Modul sinnvoll in kleinere Teile auf. Dadurch kannst du die verschiedenen Phasen der Entwicklung parallelisieren und überlagern. Nachdem der erste Teil integriert wurde, kann dieser bereits von deinem Team gereviewed und im Test-System getestet werden. Dabei kann direkt geschaut werden, ob die umliegende Logik des Systems weiterhin funktioniert.

Währenddessen kannst du schon den nächsten Teil des großen Features entwickeln. Auf diese Weise erreichst du einen hohen Durchlauf, was nicht nur theoretisch dahergesagt ist, sondern in der Praxis wirklich merkbar. Die kleinen Tickets werden auch als kleine Losgrößen bezeichnet, zumindest in der Theorie. Die Prinzipien dahinter werden im Rahmen der flussbasierten Produktentwicklung ausgeführt (engl. Product Development Flow).

Hinweis: Wenn du dich hierzu einlesen willst, sieh dir das Buch “The principles of product development flow” an . 1 

Automatisierte Tests

Dass du in deine Software Tests einbauen solltest, um Fehler schnell zu finden, ist dir wahrscheinlich bekannt. Allerdings macht es auch einen Unterschied, ob du die Tests händisch ausführen musst oder ob dies automatisch passiert.

Früher haben unsere Developer die Tests lediglich auf der lokalen Maschine ausgeführt. Die Ergebnisse sind dort dieselben, wie wenn man sie auf dem Server ausführen würde, jedoch gibt es ein paar Nachteile.

  • Erstens kannst du während der Dauer der Tests nicht einwandfrei weiterarbeiten, weil der Computer mit dem Ausführen der Tests beschäftigt ist.
  • Zweitens muss dein Team selbst daran denken, die Tests auszuführen. Du kannst es zwar immer wieder erwähnen und in den Köpfen platzieren, allerdings wird es zwangsweise auch in manchen Fällen vergessen werden. Das ist nicht gut, weil dadurch ein Schritt der Qualitätssicherung fehlt.
  • Drittens hast du die Ergebnisse dann nur lokal. Um gemeinsam darauf zuzugreifen, musst du die Test-Ergebnisse händisch deinen Mitarbeiter*innen schicken.
  • Viertens hast du mit automatisierten Tests direkt die richtigen Versionen der Software auf der Maschine. Wenn ein*e Developer*in aus einem anderen Projekt deine Pull Request reviewed, kann es sonst vorkommen, dass ihr unterschiedliche Versionen installiert habt (etwa von MySQL, PHP oder Laravel). Dieses Problem umgehst du, indem du die Tests auf einer passenden Maschine ausführst und sie so für alle sichtbar sind.

 

[Über Code-Reviews haben wir übrigens diesen Blogartikel geschrieben. Wir zeigen dir dort, wie du damit die Code-Qualität deines Teams verbesserst.]

Diese Probleme haben wir gelöst, indem wir die automatisierten Tests in unsere Pipeline eingebaut haben. Sobald jemand eine Pull Request erstellt, werden die Tests angestoßen (außerdem, wenn die PR verändert wird). Die Tests laufen dabei auf einem Server in der Cloud, wodurch man nicht vom Arbeiten abgehalten wird. Schlagen Tests fehl, dann erhält der/die Developer*in eine E-Mail mit der entsprechenden Informationen, inklusive den genauen Test-Ergebnissen. Diese E-Mail geht zudem an den/die Lead Developer*in des Teams als auch an die Projektmanager*innen. Dann wird alles daran gesetzt, dass man dem- oder derjenigen Developer*in hilft, die Probleme zu beheben.

Unsere Tests laufen übrigens über Laminar. Das haben wir über Webhooks und die API mit BitBucket integriert.

Deployments automatisieren

Vor einigen Jahren noch haben wir neue Software-Releases händisch auf die Server aufgespielt. Dazu mussten wir uns allerdings gegebenenfalls mehrere Stunden am Tag freihalten. Und da es händisch geschehen ist, bestand immer die Gefahr, dass wir aus Versehen einen notwendigen Schritt übersehen oder falsch ausführen.

Aufgrund des Aufwands haben wir nicht jeden Tag ein neues Update ausgespielt, sondern nur etwa alle ein oder zwei Wochen. Damit lieferten wir auch nur in diesem Rhythmus neue Features, wodurch wir Geschwindigkeit verloren haben und weniger flexibel waren.

Mittlerweile haben wir unsere Deployment-Pipeline schon lange automatisiert. Sobald wir eine Pull Request als Production-ready erachten, mergen wir diese und stoßen die Pipeline mit einem Button-Klick an. Nachdem aus dem Code ein Artefakt gebuildet wurde, deployen wir es mit ebenso wenig Klicks auf den Server. Dieser ganze Prozess dauert nur wenige Minuten.

Wir nutzen dafür Bamboo, was eine gute Integration an unser Code-Verwaltungs-Tool BitBucket besitzt.

Blue-Green Deployments mit Loadbalancern

Wo es für uns ohne viel Aufwand möglich ist, setzen wir auf Blue-Green-Deployments. Mit Blue-Green-Deployments ist gemeint, dass man mehrere Server online hat und zum Zeitpunkt des Deployments einfach die Requests auf den nicht gerade zu aktualisierenden Server umleitet. Damit vermeidet man Unterbrechungen in der Nutzung des Systems.

Technisch lässt sich das sehr einfach mit z. B. Loadbalancern abbilden. Dort kannst du etwa einstellen, dass die Hälfte der Requests auf Server A (Blau) und die andere Hälfte auf Server B (Grün) geleitet wird. Du kannst aber auch alle Requests zu Server A leiten, während B keine Requests bekommt. Beim Deployment wird zunächst auf den Server B ausgeliefert. Danach stellst du im Loadbalancer die Gewichtung so um, dass alle Requests auf B gehen. In diesem Augenblick hast du keinerlei Downtime oder Ähnliches. Allerdings liegt in dieser Zeit die gesamte Last auf Server B. Daraufhin wird auf A deployed. Das Deployment wird damit abgeschlossen, dass du wieder alle Requests Richtung A leitest.

Diese ausgefeilte Infrastruktur lässt sich in gängigen Cloud-Admin-Panels konfigurieren, sei es AWS (Amazon Web Services) oder, was wir nutzen, in der OTC (Open-Telekom-Cloud).

Wir empfehlen dir, diesen gesamten Prozess zu automatisieren, sprich, via Button-Klick auslösbar zu machen. Händische Konfigurationen sind nun mal fehleranfällig und in der Regel langsamer. Selbst wenn uns hier nie ein Fehler passiert ist: Man sollte die Gefahr so weit wie möglich minimieren.

Aus diesem Grund haben wir das Umstellen des Loadbalancers in ein Skript ausgelagert. Mit Terraform kann man das gut abbilden.

Weitere Stellen

Du kannst noch viele weitere Bereiche optimieren und automatisieren. Zum Beispiel haben wir auch unseren Review-Prozess automatisiert, wo man sich nun durch Emoji-Reaktionen in Slack ein Ticket zuweisen kann. Das haben wir mit nützlichen Slack-Workflows kombiniert.

Wenn du unseren Workflow und unsere Deployment-Pipelines mal in Action sehen willst: Wir sind immer auf der Suche nach neuen, netten Arbeitskolleg*innen. Bewirb dich doch und lerne unsere Arbeitsweisen beim Probetag kennen!

Fazit

Du siehst, die Automatisierung dieser wichtigen Prozesse bietet dir viele Vorteile. Dabei kommt es nicht nur auf die großen Stellen an, wie beispielsweise die Automatisierung der Tests. Stattdessen kannst du den Prozess auch mit Kleinigkeiten schon stark verbessern. Richtig gut wird es aber erst, wenn du die Pipeline von vorne bis hinten sinnvoll automatisiert hast. So gibst du jedem und jeder Developer*in den notwendigen Freiraum, um sich auf die wirkliche Arbeit zu konzentrieren.

Wobei können wir dich sonst noch unterstützen?

Neues Projekt

Du hast eine Idee für eine digitale Lösung und suchst einen Partner, der dich begleitet?

Verstärkung für dein Projekt

Du hast bereits eine Anwendung und suchst Verstärkung in der Entwicklung?

1 Mehr zur Flussbasierten Produktentwicklung: Reinertsten, D. G., The principles of product development flow: second generation lean product development 2009

Artikel teilen

Share on facebook
Share on twitter
Share on linkedin
Share on xing
Share on whatsapp

Mehr aus unserem Blog

Mockups

Was genau ist eigentlich ein Mockup? Wir erklären dir was unter dem Begriff zu verstehen ist.