Wissen ist wertvoll, aber seine wahre Stärke liegt darin, wie wir es in die Praxis umsetzen. Bei Freyr Digital waren wir mit DevOps, den dazugehörigen Methoden und dem Potenzial vertraut, unsere Organisation in ein leistungsstarkes Produktentwicklungszentrum zu verwandeln – das in der Lage ist, unseren Kunden aus den Life Sciences hochwertige Produkte und Lösungen zu liefern. Zu Beginn unserer Reise schufen unsere Bemühungen ein starkes Fundament, doch um wirklich ein Zentrum der Entwicklung zu werden, wussten wir, dass wir einen strategischeren und anpassungsfähigeren Ansatz verfolgen mussten.
Die größte Herausforderung bei der Umsetzung von Wissen in die Praxis besteht darin zu wissen, wann man die richtigen Schritte einleitet. Da Handlungen viele Menschen in einem Unternehmen betreffen, hängt das richtige Vorgehen zum richtigen Zeitpunkt davon ab, wo wir als Organisation stehen, welche Prozesse und Vorgehensweisen wir aktuell nutzen sowie über welche Fähigkeiten und Kompetenzen unsere Mitarbeiter verfügen.
Dies markierte einen Wendepunkt in unserer Transformation. Als Anbieter von Softwarelösungen mit Schwerpunkt auf maßgeschneiderten Produkten hatten wir ein engagiertes Team, das stets den entscheidenden Schritt weiterging, um Ergebnisse zu liefern. Wir erkannten jedoch die Chance, die Qualität zu steigern, die Produktivität zu erhöhen und die Umsetzung von Geschäftsanforderungen in konkrete Ergebnisse zu beschleunigen. Anstatt uns auf Last-Minute-Korrekturen zu konzentrieren, wollten wir von reaktiver Problemlösung zu proaktiver Innovation übergehen und skalierbare, wirkungsvolle Lösungen entwickeln.
Wir hatten eine klare Vision davon, wo wir stehen wollten – wie wir arbeiten, entwickeln, testen, bereitstellen und Software veröffentlichen wollten. Uns war jedoch bewusst, dass das Erreichen dieser Ziele eine durchdachte Strategie, kontinuierliches Lernen und die Entschlossenheit zur Verbesserung erfordert.
Spulen wir vor bis heute: Im vergangenen Jahr haben wir über 100 Releases mit nahezu null Fehlern bei der Bereitstellung durchgeführt und eine fast vollständige Automatisierung bei der Einführung von Änderungen erreicht. Darüber hinaus verzeichnen wir erhebliche Umsatzsteigerungen, schlankere und agilere Teams sowie eine allgemeine Entwicklung hin zu unserer Vision, ein führender Anbieter von Softwareprodukten, -lösungen und -diensten zu werden. Es gibt zwar immer noch viel zu erreichen, aber wir sind zuversichtlich, dass wir ein starkes Fundament geschaffen haben und bereit sind, das Tempo zu erhöhen.
Auf unserem weiteren Weg nehmen wir uns kurz Zeit, um über unsere Transformation nachzudenken – was funktioniert hat, was nicht und welche Lehren wir daraus gezogen haben. Indem wir unsere Erfahrungen teilen, möchten wir andere dabei unterstützen, ähnliche Veränderungen zu meistern.
Diese Blog-Serie ist größtenteils praxisorientiert. Sie zeigt auf, was wir getan haben, und verbindet unsere Maßnahmen gleichzeitig mit bewährten Methoden und Empfehlungen aus verschiedenen DevOps- und Agilen Ressourcen.
Das Richtige zur richtigen Zeit tun
Einer der Schlüsselaspekte unserer Transformation bestand darin, die richtigen Maßnahmen zum richtigen Zeitpunkt zu ermitteln. Angesichts mehrerer möglicher Initiativen benötigten wir einen strukturierten Ansatz, um sinnvolle Fortschritte sicherzustellen.
Rückblickend können wir diese Maßnahmen in drei Kategorien einteilen: Tools und Prozesse, Softwarearchitektur und Menschen. Diese Bereiche sind eng miteinander verknüpft, sodass Änderungen in einem Bereich Auswirkungen auf die anderen haben. Dennoch war es möglich, in jeder Kategorie schrittweise Änderungen vorzunehmen und die Fortschritte im Hinblick auf unsere Gesamtziele zu messen.
Die Initiativen in diesen Kategorien waren oft voneinander abhängig. Veränderungen in einem Bereich eröffneten Möglichkeiten für weitere Verbesserungen in einem anderen.
Die ersten Schritte
Um eine solide Grundlage zu schaffen, konzentrierten wir uns auf drei Kerninitiativen:
- Verknüpfung unserer Quellcodebasen mit SonarQube zur Erfassung von Kennzahlen zur Code-Qualität.
- Umstellung aller Teams auf ein gemeinsames Tool zur Verwaltung von Anforderungen, Quellcode und Testplänen – in unserem Fall Azure DevOps.
- Strukturierung der Teams mit klaren Verantwortlichkeiten zur Stärkung von Eigenverantwortung und Rechenschaftspflicht.
Diese drei Initiativen gaben uns Einblick in:
- Die auszuführende Arbeit (Anforderungen und Aufgaben).
- Die Code-Qualität (SonarQube-Kennzahlen).
- Die beteiligten Personen (Teamverantwortlichkeiten).
Unter diesen war die Festlegung klarer Teamverantwortlichkeiten die größte Herausforderung. Anfangs waren die Teamstrukturen fließend, wobei Personen je nach Bedarf projektübergreifend eingesetzt wurden. Der Übergang zu dedizierten Teams mit klar abgegrenzten Funktionsbereichen war ein notwendiger Schritt, der jedoch durch unsere bestehende Produktarchitektur erschwert wurde, da diese nicht vollständig auf eine eindeutige Zuständigkeit ausgelegt war.
Die Rolle der Softwarearchitektur
Wir haben schnell erkannt, dass die Produktarchitektur einer der wichtigsten Bereiche für Veränderungen war. Eine modulare Architektur war unerlässlich, damit unabhängige Teams die Verantwortung für ihre Arbeit übernehmen konnten. Ohne dies wären unsere Bemühungen um mehr Eigenverantwortung der Teams nur von geringem Erfolg gekrönt gewesen.
Die Neugestaltung unseres Portfolios war ein komplexer Prozess. Dazu gehörte die vollständige Verlagerung in die Cloud und die Entwicklung Cloud-nativer Anwendungen mithilfe einer Mikroservices-Architektur. Dieses Thema wird in einem späteren Beitrag behandelt. Die wichtigste Erkenntnis ist jedoch, dass Änderungen schrittweise erfolgen und bestimmte Schritte erforderlich sind, um Vorteile und weitere Fortschritte zu erzielen.
Kennzahlen und kontinuierliche Verbesserung
Nachdem wir mit der Neugestaltung begonnen hatten (ein fortlaufender Prozess), verlagerten wir unseren Schwerpunkt auf das Überwachen von Kennzahlen und das Festlegen von Zielen:
- Kennzahlen zur Code-Qualität in SonarQube.
- Kennzahlen zur Code-Integration in Azure DevOps.
- Kennzahlen zum Funktionsdurchsatz für einzelne Teams.
- Einführung Cloud-nativer Services.
Diese Ziele waren keine strengen Vorgaben, sondern Orientierungspunkte, die den Teams helfen sollten, ihre Arbeit aufeinander abzustimmen.
Unterstützung für die Mitarbeitenden
Mit den eingeführten Kennzahlen wurde deutlich, dass die Teams Unterstützung brauchten, um diese Ziele zu erreichen. Während die Vorgaben für die Unit-Test-Abdeckung und die API-Testautomatisierung zwar klar waren, stellte sich deren Umsetzung als schwierig heraus – insbesondere bei älterem Code, der nicht auf Testbarkeit ausgelegt war.
Um dies zu lösen, haben wir folgende Maßnahmen ergriffen:
- Niedrigere Ziele für älteren Code festgelegt.
- Workshops und praxisnahe Schulungen zum Schreiben hochwertiger Unit-Tests und zum Entwerfen testbarer Codes organisiert.
- Anleitungen zum Erstellen von Stubs für API-Tests bereitgestellt.
- Überprüfungen von Unit-Tests durch leitende Architekten durchgeführt.
Das Dreieck aus Tools, Architektur und Mitarbeitenden
Ein gutes Beispiel für das Zusammenspiel dieser Bereiche war die Code- und Repository-Verwaltung. Die Anbindung an SonarQube – eine Verbesserung bei den Tools – zeigte eine geringe Unit-Test-Abdeckung auf, was wiederum auf architektonische Probleme hinwies, die die Testbarkeit einschränkten. Verbesserungen bei der Architektur und den Fähigkeiten des Teams führten zu qualitativ besseren Unit-Tests, die jedoch aufgrund ungünstiger Branching-Praktiken nicht regelmäßig ausgeführt wurden. Wir haben dies gelöst, indem wir Branching-Strategien standardisiert und sichergestellt haben, dass Code regelmäßig in den Hauptbranch integriert wird, damit CI-Pipelines alle Tests ausführen können.
Die richtige Reihenfolge von Änderungen
Ein möglicher Ansatz für eine Transformation besteht darin, Best Practices undifferenziert anzuwenden. Zwar bringt dies möglicherweise Vorteile, doch die Ergebnisse rechtfertigen oft den Aufwand nicht, was zu Frustration führt.
Wir folgten einem anderen Ansatz, der auf dem Prinzip des Flusses basiert: Den End-to-End-Prozess analysieren, Engpässe identifizieren und diese schrittweise beheben.
Jede Verbesserung deckte neue Engpässe auf, die weiteres Handeln erforderten. Dies war kein bloßes „Hauen und Stechen“, sondern ein bewusster Prozess, bei dem zur richtigen Zeit das Richtige getan wurde.
Beispielsweise hätte die Vorgabe einer Unit-Test-Abdeckung ohne Verbesserung des Code-Designs zu Frustration und einer „Scheinabdeckung“ geführt (oberflächliche Tests, die nur geschrieben wurden, um Kennzahlen zu erfüllen). Indem wir uns zuerst um Architektur und Fähigkeiten gekümmert haben, sorgten wir für sinnvolle Fortschritte.
Ausblick
Eine echte Transformation besteht nicht aus einem einzigen großen Umbruch, sondern aus klugen, gut timten Entscheidungen, die einen kontinuierlichen Fortschritt antreiben. Wir freuen uns, unsere Erfahrungen und Erkenntnisse zu teilen, um anderen dabei zu helfen, ihren eigenen Weg zu einer skalierbaren, wirkungsvollen Veränderung zu gehen.
In den kommenden Blogs dieser Reihe – DevOps for the Win – zeigen wir, wie jede Phase unserer Transformation im DevOps-Dreieck aus Tools, Architektur und Menschen uns geholfen hat, eine nachhaltige Wirkung zu erzielen.
