Im letzten Jahr hat Driftrock eine ziemlich typische Entwicklung durchlaufen – vielleicht habt ihr das schon einmal gehört: Wir haben uns von manuellen Bereitstellungen und einer gewissen Gleichgültigkeit gegenüber der Softwarebereitstellung hin zu automatisierten und wiederholbaren Bereitstellungen entwickelt, bei denen die Wertschöpfung im Mittelpunkt steht.
Anstatt euch mit einem weiteren Beitrag über die Vorzüge von Continuous Delivery zu langweilen – auch wenn ich das eigentlich gerne täte –, möchte ich mich stattdessen darauf konzentrieren, wie wir diesen Wandel erreicht haben. Inspiriert durch das Buch „More Fearless Change“ von Mary Lynn Manns und Linda Rising werde ich mein Bestes tun, um mich an die Schritte zu erinnern, die wir unternommen haben, und insbesondere an die Muster, die wir weiterhin anwenden, um das Verhalten des Teams zu verändern.
Ein paar Jahre zurückblicken
Zunächst etwas Hintergrundinformation: Im Juni 2016 gelangte jede Änderung an einer unserer Anwendungen auf verschlungenen Pfaden in die Produktion. Es gab kaum einen Überblick darüber, ob eine Änderung tatsächlich bereitgestellt worden war; es gab ein frustrierend verbreitetes Verzweigungsmodell, das die kognitive Belastung drastisch erhöhte, und Bereitstellungen wurden manuell vom Rechner eines Entwicklers aus über die Heroku-CLI ausgelöst.
Ein neuer Wechsel von der Entwicklungs- zur Produktionsumgebung sah in etwa so aus:

Grün – automatisierter Schritt.
Orange – unvermeidbarer manueller Schritt oder ein manueller Schritt, den wir (noch) nicht ändern wollen.
Rot – vermeidbarer manueller Schritt.
Je nach Anwendung gab es zudem eine Reihe von Unstimmigkeiten in diesem Bereitstellungsprozess. Einige Anwendungen verfügten über keine Staging-Umgebung; bei denjenigen, die eine hatten, war nicht sicher, ob die Bereitstellung in der Staging-Umgebung automatisch erfolgte, und nicht bei allen Anwendungen wurden automatisierte Tests auf dem Master-Zweig oder anderen Zweigen ausgeführt. Kurz gesagt: Der Prozess war unnötig komplex, äußerst uneinheitlich und wies kaum bis gar keine Automatisierung auf. Es ist daher nicht verwunderlich, dass das Team wenig Interesse an der Bereitstellung von Software zeigte.
All dies führte dazu, dass die Bereitstellungen unregelmäßig und risikobehaftet waren. Meistens wurde eine große Menge an Änderungen auf einmal live geschaltet, was die Wahrscheinlichkeit, dass etwas schiefging, vorhersehbar erhöhte und manchmal die Möglichkeit eines sicheren Rollbacks zunichte machte.
Kleine Schritte
Ich werde versuchen, die von uns unternommenen Schritte und die entsprechenden Muster zu erläutern, mit denen wir das oben beschriebene Szenario verbessert haben. Ganz unten auf dieser Seite finden Sie eine Referenz zu den in diesen Schritten erwähnten Mustern. Außerdem finden Sie hier eine übersichtliche Auflistung und Beschreibung aller Muster.
Schritt 1 – Alle einbeziehen
Ungewöhnlicherweise begann alles mit der Verbesserung unserer Retrospektiven. Das Team brauchte eine Plattform, um Probleme zu besprechen und Verbesserungsvorschläge zu machen (Involve Everyone). Zwar hielten wir wöchentlich ein Gespräch ab, das wir Retrospektive nannten, doch hatte dies wenig Ähnlichkeit mit den Retrospektiven, die ich bei mehreren anderen Unternehmen erlebt hatte. Ursprünglich ähnelte dieses Treffen eher einem wöchentlichen Status-Update; der Fokus lag auf den täglichen Arbeitsaufgaben und deren Fortschritt, anstatt zu prüfen, wie wir unsere Arbeitsweise verbessern können. Der Vorschlag und die anschließende Demonstration eines strukturierteren Ansatzes für Retrospektiven (durch die Moderation der ersten paar Retros) hatten einen erheblichen Einfluss auf das Team, der über Continuous Delivery hinausging, aber einer der ersten Diskussionspunkte drehte sich darum, wie wir unsere Software bereitstellen (Plant the Seeds).
Schritt 2 – Einfach loslegen
Da das Team sich nicht ganz sicher war, welche Vorteile ein Umstieg auf Continuous Delivery für sie haben könnte, war der nächste Schritt ganz einfach: Ich zeigte ihnen ein Beispiel (Just Do It). Ich stellte eine einfache HTTP-API-Anwendung mit einem Endpunkt zusammen, der „200 OK“ zurückgab, und erstellte eine Deployment-Pipeline in Snap CI. Ich versuchte nachzuahmen, wie wir unsere regulären Anwendungen behandeln würden, und ging nur die unmittelbarsten Probleme an (Pick Your Battles): manuelle Deployments und die Verwaltung mehrerer Branches beim Deployment. Letzteres verringerte zudem die Kluft zwischen lokaler Entwicklung und Produktion. Damit demonstrierte ich, dass sich unser Deployment-Prozess in folgende Richtung entwickeln könnte:

Wie zu erwarten war (genau wie bei funktionierender Software), wurde dies zu einem hervorragenden Beispiel, um den Nutzen von CD zu demonstrieren und zu erläutern und um zu zeigen, wie sich dies von unseren bisherigen Vorgehensweisen unterscheidet.
Schritt 3 – Testlauf
Nachdem der Grundstein gelegt war, die Akzeptanz im Team stetig wuchs – dank eines funktionierenden Beispiels und der regelmäßig auftretenden Probleme bei der Bereitstellung hochwertiger Software (die nur die Schwere der Situation verdeutlichten – ein Weckruf). Der nächste Schritt bestand darin, das Team dazu zu bewegen, ein oder zwei echte Anwendungen auf das neue System zu migrieren (Testlauf). Wir wählten zwei problematische Anwendungen aus, um unsere Annahmen so früh wie möglich zu validieren, erstellten Deployment-Pipelines für sie, führten die Bereitstellung erfolgreich durch und ließen diese Veränderung sich einpendeln. Zu diesem Zeitpunkt hatte ich glücklicherweise Unterstützung (um Hilfe bitten), was den Fortschritt deutlich beschleunigte und es einfacher machte, mit möglichen Gegenreaktionen umzugehen.
Schritt 4 – Kontinuierliche Öffentlichkeitsarbeit
Ein Muster, das in dem Buch erwähnt wurde, ist mir während dieses gesamten Prozesses besonders aufgefallen – „Persistent PR“. Im Nachhinein betrachtet tauchte dieses Muster an mehreren Stellen auf, manchmal bewusst, oft aber auch unbewusst. Hier eine Übersicht darüber, wo es vorkam:
- Wir haben unser regelmäßiges Stand-up-Meeting so umgestaltet, dass es sich zunächst auf das konzentriert, was in die Produktion übernommen wurde, dann auf die Staging-Umgebung und schließlich auf die aktive Entwicklung – was gemeinhin als „Walk the Board“ bekannt ist. Auch wenn dies nur indirekt geschieht, erinnert es das Team regelmäßig daran, sich in erster Linie auf die Auslieferung von Software zu konzentrieren und darauf, wie wir Arbeitsaufgaben in die Produktion überführen können.
- Bei einer wöchentlichen Betriebsversammlung haben wir kurz vorgeführt, wie wir unseren Ansatz bei der Softwarebereitstellung geändert haben. Das ergab sich zwar eher zufällig, aber es war eine Gelegenheit, die es wert war, genutzt zu werden (Smell of Success).
- Wir haben damit begonnen, Kennzahlen zur Anzahl der Produktivbereitstellungen zu erfassen und zu kommunizieren.
- Wir haben einige Rückkopplungsmechanismen eingeführt, um den Informationsfluss rund um die Bereitstellungen zu verbessern:
- Slack-Benachrichtigungen – die Übermittlung von Informationen über fehlgeschlagene Builds oder erfolgreiche Bereitstellungen. So mussten die Entwickler nicht mehr selbst nach dem Status ihrer Änderung suchen, sondern wurden automatisch darüber informiert.
- Versionshinweise – Wir haben damit begonnen, Änderungen, die für unsere Kunden relevant sind, intern bereits bei ihrer Einführung bekannt zu geben. Dies hat dazu beigetragen, das Interesse und die Diskussion über neue Funktionen bei den Mitarbeitern im gesamten Unternehmen zu wecken.
- Überwachung – ein Bereich, den wir noch nicht vollständig ausgereift haben, aber wir experimentieren weiterhin mit Überwachungsmaßnahmen und besseren Möglichkeiten, Feedback aus unseren Produktionssystemen zu sammeln.
Also, wo stehen wir jetzt?
Derzeit führen wir etwa 15 Mal pro Woche Produktivbereitstellungen durch – ein gutes, nachhaltiges Tempo für ein Team unserer Größe. Letztendlich haben wir etwa 30 Projekte auf Snap CI umgestellt. Wir haben CD-Pipelines für eine Vielzahl von Anwendungen erstellt: Ruby-Gems, Elixir-Pakete, auf AWS gehostete statische Websites, Webanwendungen auf Heroku und andere, die in Kubernetes gehostet werden. Jeder im Team übernimmt die Verantwortung dafür, dass eine Änderung, an der er arbeitet, in die Produktion bereitgestellt wird, und arbeitet eng mit anderen Teammitgliedern zusammen, um die entsprechenden Funktionen zu testen. Wir verlassen uns zunehmend auf automatisierte Tests, Feature-Toggles und Abwärtskompatibilität – Themen, die in unseren Retrospektiven eine große Rolle gespielt haben.
Nebenbei bemerkt: Snap CI hat die Erwartungen nicht wirklich erfüllt, aber selbst das hatte einige positive Aspekte. Nachdem wir mit verschiedenen Problemen zu kämpfen hatten, begannen wir, in den Einsatz von Docker für die CI zu investieren, um die Build-Umgebung zu isolieren und die Kontrolle darüber zu übernehmen. Dies hatte zahlreiche Folgewirkungen, wie zum Beispiel den Einsatz von Docker in der Entwicklung und den Übergang zu Kubernetes. Außerdem verringerte es unsere Abhängigkeit von einem bestimmten CI/CD-Tool, was sich bald als sehr wichtig erwies, als Snap CI seine Einstellung ankündigte. Glücklicherweise sind wir nun viel besser in der Lage zu verstehen, was wir brauchen, und sind daher dabei, auf Buildkite umzusteigen (ein Thema für einen anderen Artikel!).
Hoffentlich gibt Ihnen das einen Einblick darin, wie wir unseren Übergang zu Continuous Delivery fortsetzen und welche Vorgehensweisen uns dabei geholfen haben. Unser Ansatz entwickelt sich weiter, während wir lernen, und wir sind uns bewusst, dass wir noch einen weiten Weg vor uns haben. All diese Bemühungen in vier Schritten zusammenzufassen, ist sicherlich eine starke Vereinfachung – selbst für unser kleines Team hat es viele Monate gedauert, bis wir dort angekommen sind, wo wir jetzt stehen. Diese Reise hat uns daran erinnert, dass eine solche Veränderung nicht über Nacht geschieht und dass es viele kleine, unscheinbare Schritte in die richtige Richtung braucht.
Weitere hilfreiche Ressourcen
Linda Rising – Mythen und Muster des organisatorischen Wandels
Continuous Delivery – Jez Humble & Dave Farley
Continuous Delivery – Vom Tellerwäscher zum Millionär – Hibri Marzook
Trunk-basierte Entwicklung
Referenz zu Veränderungsmustern
Um es mit den Worten des Buches etwas frei wiederzugeben, hier eine Auswahl der Muster, die ich oben erwähnt habe:
Kleine Schritte – Gehen Sie Schritt für Schritt auf Ihr Ziel zu.
Alle einbeziehen – Jeder sollte die Möglichkeit haben, seinen eigenen Beitrag zu leisten.
Die Saat säen – Nutzen Sie jede Gelegenheit, um Interesse an einer Idee zu wecken.
Einfach loslegen – WartenSie nicht auf den perfekten Moment, sondern machen Sie den ersten kleinen Schritt und fangen Sie an zu lernen.
Wähle deine Schlachten – Konzentriere deine Bemühungen auf die dringendsten Probleme.
Probelauf – Wenn es Widerstände gegen eine Idee gibt, schlage ein Experiment für einen kurzen Zeitraum vor.
Weckruf – Weise auf die Probleme hin, die einen Veränderungsbedarf schaffen.
Bitten Sie um Hilfe – Suchen Sie nach Menschen und Ressourcen, die Ihre Bemühungen unterstützen, und fördern Sie deren Einbindung.
Beharrliche Öffentlichkeitsarbeit – Halten Sie die neue Idee im Blickfeld aller und bewerben Sie sie konsequent auf vielfältige Weise.
Der Duft des Erfolgs – Wenn Ihre Bemühungen zu einem sichtbaren positiven Ergebnis führen, nutzen Sie dies als Gelegenheit, daraus zu lernen.