7 Min. Lesezeit
Vom Monolithen in die Cloud: Cloud Migrationen automatisieren
Einleitung – Cloud-Migrationen erfolgreich meistern
Die Migration von Anwendungen in die Cloud ist ein komplexes Unterfangen mit erheblichen technischen und organisatorischen Auswirkungen. Sie erfordert die Bewertung der Cloud-Readiness, die Auswahl der richtigen Migrationsstrategie und bei Bedarf die Anpassung des Quellcodes. Automatisierte Tools spielen mittlerweile eine Schlüsselrolle bei der Analyse und Transformation von Softwareprojekten.
Dieser Artikel stellt zwei Open-Source-Tools vor: das CNCF-Projektt Konveyor und OpenRewrite von Moderne, die bei der Planung und Durchführung der Migration von Java-basierten Unternehmensanwendungen unterstützen. Wir decken sowohl strategische Überlegungen als auch technische Workflows bis hin zu Anpassungen auf Code-Ebene ab.
Warum das wichtig ist
Cloud-Plattformen versprechen Skalierbarkeit, Resilienz, Automatisierung und Kostenkontrolle. Legacy-Systeme sind jedoch oft monolithisch aufgebaut und eng an spezifische Infrastrukturen gekoppelt. Eine erfolgreiche Migration erfordert maßgeschneiderte Strategien; weder ein einfaches „Lift and Shift“ noch ein vollständiger Rewrite sind immer die optimale Lösung.
Schlüssel zum Erfolg
Erfolgreiche Projekte halten die Waage zwischen Kosten, Funktionalität und Modernisierung. Sie setzen auf interdisziplinäre Teams, klare Kommunikation und Tools, die transparente Analysen und reproduzierbare Änderungen liefern. Konveyor hilft bei der Evaluierung des Migrationsbedarfs, während OpenRewrite Code-Updates automatisiert – und dabei typische Probleme wie Classpath-Konflikte, Logging-Frameworks, Konfigurationen und veraltete Servlet-Container löst.
Herausforderungen – Komplexität sichtbar machen
Eine Cloud-Migration ist nicht bloß eine technische Übung, sondern eine architekturelle Entscheidung mit weitreichenden Konsequenzen. Sie betrifft den Quellcode, Build-Prozesse, Infrastrukturabhängigkeiten, Bereitstellungsstrategien und Sicherheitsanforderungen. Typische technische Hürden sind:
- Eng gekoppelte Komponenten ohne wohldefinierte Schnittstellen
- Hartcodierte Konfigurationen, die Umgebungswechsel erschweren
- Direkte Nutzung von Infrastrukturressourcen wie lokalen Dateisystemen oder Datenbanken
- Veraltete Frameworks oder nicht mehr unterstützte Bibliotheken

Typische Hürden bei der Cloud-Migration. Bild generiert mit ChatGPT.
Eine weitere Herausforderung ist das Fehlen einer einheitlichen Teststrategie. Anwendungen ohne reproduzierbare Builds, automatisierte Tests oder Infrastructure-as-Code lassen sich nur schwer in automatisierte CI/CD-Pipelines integrieren – doch solche Pipelines sind für den cloud-nativen Betrieb unverzichtbar.
Bewertung der Cloud-Readiness mit Konveyor
Ein zentrales Konzept, das wir bei QAware bei der Bewertung der Cloud-Readiness (Cloud-Bereitschaft) nutzen, ist die Kategorisierung von Anwendungen in drei Gruppen:
- Cloud-alien (cloud-fremd): Stark monolithische oder technologisch veraltete Anwendungen mit minimaler Entkopplung und komplexen Abhängigkeiten.
- Cloud-friendly (cloud-freundlich): Weisen bereits einige cloud-native Eigenschaften auf (z. B. externalisierte Konfiguration, modulare Architektur), erfüllen aber noch nicht alle Kriterien vollständig.
- Cloud-native (cloud-nativ): Von Grund auf für die Cloud konzipiert. Diese Anwendungen nutzen Container, sind zustandslos, horizontal skalierbar und leicht zu automatisieren.

Kategorien der Cloud-Readiness.
Konveyor verwendet eine ähnliche Klassifizierung, die durch die Analyse automatisch und transparent generiert wird. Zu den wichtigsten Prüfungen gehören:
- Nutzung veralteter oder proprietärer Frameworks
- Abhängigkeit vom Dateisystem oder lokalem Zustand
- Direkter Datenbankzugriff ohne Abstraktion
- Fehlen von Schnittstellen für Logging und Monitoring
Überblick über das Konveyor-Projekt
Das Konveyor-Projekt besteht aus drei Hauptkomponenten:
- Einer bereitstellbaren Webanwendung namens Konveyor Hub für die Migrationsplanung, bestehend aus drei Modulen:
- Application Inventory: Dient als Portfolio-Management-System. Es ermöglicht das Katalogisieren von Anwendungen, das Verknüpfen mit Geschäftsdiensten wie Jira, das Definieren von Abhängigkeiten und das Hinzufügen von Metadaten über ein erweiterbares Tagging-Modell.
- Assessment Module (Pathfinder): Ein Fragebogen-basiertes Tool innerhalb von Tackle, das die Eignung einer Anwendung für die Containerisierung (z. B. Kubernetes) bewertet. Es identifiziert Risiken, bewertet die Einsatzbereitschaft und erstellt Berichte zur Erstellung eines Migrationsplans.
- Analysis Module: Analysiert Quellcode und Abhängigkeiten mithilfe vordefinierter oder benutzerdefinierter Regeln. Die Analyse liefert einen detaillierten Bericht, der alle Probleme aufzeigt, die eine Migration zu Kubernetes blockieren könnten, und liefert Aufwandsschätzungen.
-
Ein CLI-Tool namens Kantra das die Analysefunktionen in einer eigenständigen Befehlszeilenschnittstelle kapselt. Es analysiert Quellcode sowie Abhängigkeiten, erstellt Berichte über Migrations-Blocker und liefert konkrete Handlungsempfehlungen.
-
Eine neue Komponente zur Integration von KI-Funktionen namens Konveyor AI. Sie nutzt die Analyseergebnisse und stellt mithilfe von Generativer KI automatische Fixes bereit. Diese Komponente befindet sich noch in der Entwicklung, ist aber sehr vielversprechend.
Die Analyse von Konveyor nutzt statische Codeanalyse und Heuristiken und erkennt Elemente wie JDBC-Anweisungen, Web-Frameworks, hartcodierte Pfade oder beispielsweise alte Java-Klassen. Die Ausgabe ist in HTML oder JSON verfügbar und kann direkt in CI/CD-Pipelines integriert werden.
Beispiel: Analyse einer Java-Anwendung mit der Konveyor-CLI Kantra
Um eine Java-Anwendung mit dem Konveyor CLI-Tool Kantra zu analysieren, können Sie folgende Schritte ausführen:
-
Installieren Sie die Kantra-CLI durch Herunterladen von der Kantra Releases-Seite.
- Führen Sie nach der Installation den folgenden Befehl aus, um Ihre Java-Anwendung auf Cloud-Readiness zu prüfen:
kantra \
analyze \
-i /path/to/your/java/application \
-o ../out \
--mode source-only \
--target cloud-readiness
- Überprüfen Sie den generierten Bericht, um Migrations-Blocker und Handlungsempfehlungen zu identifizieren:
Kantra generiert den Bericht im HTML-Format innerhalb des angegebenen Ausgabeverzeichnisses (in diesem Beispiel ../out).

Beispiel für einen aus der Analyse generierten Bericht.
Mit dem Bericht können Sie die Cloud-Readiness Ihrer Anwendung bewerten, potenzielle Blocker identifizieren und konkrete Erkenntnisse für Refactoring- oder Modernisierungsmaßnahmen gewinnen.
Migrationsstrategien – Drei Wege in die Cloud
Basierend auf den Analyseergebnissen können Teams eine Migrationsstrategie wählen, die zu ihrer Anwendungslandschaft und ihren geschäftlichen Zielen passt. In der Praxis haben sich drei Kernstrategien herausgebildet, die jeweils unterschiedliche Ziele, Aufwände und Risiken aufweisen.

Strategien für die Cloud-Migration.
Rehosting („Lift & Shift“)
Der Entwickler verlagert die Anwendung ohne Änderungen in die Cloud. Dieser Ansatz ist schnell und erfordert minimalen Entwicklungsaufwand, bringt jedoch keine strukturellen Verbesserungen. Er wird häufig bei kurzfristigem Kapazitätsbedarf oder Infrastrukturumstellungen (z. B. bei der Stilllegung von Rechenzentren) genutzt. Technisch kann dies bedeuten, dass VMs 1:1 zu IaaS-Angeboten wie AWS EC2 oder Azure VM migriert werden, wobei die meisten bestehenden CI/CD-Pipelines erhalten bleiben. Die Nachteile sind begrenzte Skalierbarkeit, eingeschränkte Observability und geringe Kostenvorteile – was oft zu Szenarien führt, die man als „Cloud in Name Only“ bezeichnet.
Refactoring
Der Entwickler passt die Anwendung an cloud-native Paradigmen an, was typischerweise Folgendes umfasst:
- Modularisierung und Entkopplung
- Containerisierung (z. B. Docker)
- Externalisierung von Zuständen (Sitzungen, temporäre Dateien)
- Nutzung von Umgebungsvariablen für Konfigurationen
- Einbindung von Cloud-Diensten (z. B. S3, RDS, Kafka)
Refactoring ist üblich für funktional stabile, aber technisch veraltete Anwendungen. Es ermöglicht den Abbau von technischen Schulden, stellt Observability her (Prometheus, Grafana, OpenTelemetry), ermöglicht resiliente Kubernetes-Deployments und sorgt für zukunftssichere Skalierung. Tools wie OpenRewrite erleichtern dies durch regelbasierte, reproduzierbare Codeänderungen.
Rebuilding
The developer performs a complete rewrite based on modern cloud architectures. A rewrite is necessary when:
- The current application is unmaintainable
- Business logic has fundamentally changed
- New business models (API economy, platform services) are the focus
Typische Technologien sind Microservices, Serverless-Komponenten (AWS Lambda, Azure Functions) und ereignisgesteuerte Architekturen (Event-Driven Designs). Rebuilding ist kostspielig, aber zukunftsweisend, wobei der ROI an das Innovationspotenzial gekoppelt ist.
Hybride Ansätze
Die meisten realen Migrationen kombinieren verschiedene Strategien – zum Beispiel das Refactoring des transaktionalen Kerns bei gleichzeitigem Rehosting von Hilfsmodulen. Dies verbindet einen schnellen ROI mit langfristiger Modernisierung. Eine erfolgreiche Migration hält die Balance zwischen Geschäftskontinuität und technischer Erneuerung.
OpenRewrite – Automatisierte Codetransformation
Während sich Konveyor auf Analyse und Strategieplanung konzentriert, geht OpenRewrite den nächsten Schritt: automatisierte Codeanpassungen auf Basis deklarativer Regeln.
Im Kern analysiert OpenRewrite den Code zu einem vollständigen abstrakten Syntaxbaum (AST) und ermöglicht so semantisch präzise Transformationen. Sogenannte “Recipies” (Rezepte) definieren die Transformationslogik als modulare, wiederverwendbare und versionierbare Komponenten.
Gängige Transformations-Recipies
OpenRewrite bietet ein umfangreiches Set an Community-Recipes für typische Migrationsaufgaben, wie zum Beispiel:
- Ersetzen veralteter Bibliotheken
- Migration von Spring Boot 1.x → 2.x → 3.x
- Umbenennen von Methoden, Packages oder Klassen
- Hinzufügen von Java Sicherheitsannotationen oder Aktualisieren von Abhängigkeiten
Beispiel: Upgrade von Spring Boot von 2.X auf 3.X
Mit Maven lässt sich OpenRewrite einfach in Ihren Build-Prozess integrieren und ein spezifisches Recipe anwenden.
Das folgende Beispiel zeigt, wie Sie eine Spring-Boot-Anwendung von Version 2.x auf 3.4 aktualisieren, was erhebliche Änderungen wie die Migration des Jakarta-EE-Namespaces beinhaltet.
- Fügen Sie die folgende Plugin-Konfiguration zu Ihrer
pom.xmlunter<plugins>hinzu:
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>6.15.0</version> <!-- Update to latest version -->
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_4</recipe>
</activeRecipes>
<activeStyles>
<style>org.openrewrite.java.SpringFormat</style>
</activeStyles>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>6.11.1</version> <!-- Update to latest version -->
</dependency>
</dependencies>
</plugin>
- Führen Sie das Maven Rewrite Plugin aus, um das Upgrade durchzuführen:
mvn rewrite:run
Erstellen eigener Regeln
OpenRewrite mit benutzerdefinierten Recipes erweitern
Über Community-Regeln hinaus ermöglicht Ihnen OpenRewrite das Schreiben eigener Recipes. Sie können dies deklarativ mit YAML (Kombination bestehender Bausteine) oder imperativ mit Java tun (volle Kontrolle über Transformationen auf AST-Ebene). Ein pragmatischer Mittelweg ist der Start mit Templates im Refaster-Stil, um einfache Java-Recipes schnell aufzubauen.
Deklarativ (YAML)
Wann zu verwenden: Komposition, simple Transformationen und zentral verwaltete Policy-Rollouts.
Beispiel:
# Compose existing recipes to roll out standards
name: com.company.platform.baseline
recipeList:
- org.openrewrite.java.dependencies.UpgradeDependencyVersion:
groupId: org.springframework.boot
artifactId: spring-boot-starter
newVersion: 3.3.x
- org.openrewrite.java.RemoveUnusedImports
- org.openrewrite.java.format.AutoFormat
Vorteile:
- Kombination vorgefertigter Recipes (Dependency-Upgrades, Suchen/Ersetzen, Formatierung)
- Schnelle Erstellung und einfache Überprüfung in PRs
- Zusammen mit dem Code versionierbar; leicht zu parametrisieren
Nachteile:
- Beschränkt auf bestehende Transformationen oder Community-Recipes
Imperative (Java)
Wann zu verwenden: Komplexe, kontextbezogene Refactorings, die direkten AST-Zugriff erfordern.
Minimales Recipe-Skelett:
@DocumentExample
public class ReplaceSystemOutWithSlf4j extends Recipe {
@Override public String getDisplayName() { return "Use SLF4J instead of System.out"; }
@Override public TreeVisitor getVisitor() {
return new JavaIsoVisitor<>() {
@Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation m, ExecutionContext ctx) {
m = super.visitMethodInvocation(m, ctx);
if (m.getSimpleName().equals("println") &&
TypeUtils.isOfClassType(m.getSelect().getType(), "java.io.PrintStream")) {
return m.withName(m.getName().withSimpleName("info"))
.withSelect(JavaParser.parseExpression("logger"));
}
return m;
}
}; }
}
Vorteile:
- Volle Flexibilität für anspruchsvolle Transformationen
- Kann Unternehmensregeln, Security-Hardening und Architektur-Guardrails abbilden
Nachteile:
- Höherer Aufwand; erfordert Java-/AST-Know-how
Refaster-Templates (Der Mittelweg)
Nutzen Sie Before/After-Muster im Refaster-Stil, um Java-Visitor zu generieren.
Beispiel:
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
@RecipeDescriptor(
name = "Prefer StringIsEmpty",
description = "Prefer String#isEmpty() over alternatives that check the string's length."
)
public class StringIsEmpty {
@BeforeTemplate
boolean equalsEmptyString(String string) {
return string.equals("");
}
@BeforeTemplate
boolean lengthEquals0(String string) {
return string.length() == 0;
}
@AfterTemplate
boolean optimizedMethod(String string) {
return string.isEmpty();
}
}
Wann zu verwenden:
- Simple API-Migrationen (Methodenumbenennung, Methodensignaturänderungen)
- Weit verbreitete Anpassungen von Methodenaufrufen, bei denen ein Template die Absicht klar ausdrückt
Vorteile:
- Schneller als das manuelle Erstellen von Visitoren von Grund auf
- Liefert weiterhin deterministische, überprüfbare Änderungen
Das Potenzial von LLMs bei Cloud-Migrationen: Komplementäre Intelligenz
Mit dem Aufkommen leistungsfähiger Large Language Models (LLMs) stellt sich die Frage: Wie können diese Technologien zur Cloud-Migration beitragen? Im Gegensatz zu regelbasierten Tools wie OpenRewrite arbeiten LLMs probabilistisch – sie nutzen statistische Sprachmodelle, die auf großen Codebasen und Textkorpora trainiert wurden.
Potenzielle Anwendungsbereiche
Vielversprechende Anwendungsfälle für LLMs bei der Migration sind:
- Code-Analyse: Erkennen von Code Smells, veralteten Mustern oder Sicherheitslücken im Kontext und Generieren von Verbesserungsvorschlägen mit textuellen Erklärungen.
- Refactoring-Vorschläge: Erzeugen semantisch sinnvoller Umstrukturierungen aus Prompts oder Pull Requests inklusive zugehöriger Tests.
- Konfigurationsdatei-Migration: Aktualisieren von YAML-, XML-, Helm-Charts oder Dockerfiles für neue Versionen oder Zielumgebungen.
- CI/CD-Definitionsgenerierung: Erstellen von Jenkinsfiles, GitHub Actions oder GitLab CI-Konfigurationen aus natürlicher Sprache.
- Dokumentation: Automatisches Schreiben technischer Erklärungen, Architekturdiagramm-Beschreibungen oder Changelogs direkt aus dem Code.
Vorteile
Die Stärken von LLMs liegen in ihrer:
- Flexibilität: Verstehen semantischer Zusammenhänge über Frameworks und Programmiersprachen hinweg.
- Unterstützung: Helfen Entwicklern beim Erkunden unbekannter Technologien oder beim Modernisieren von Legacy-Code.
- Rapid Prototyping: Liefern schnelle erste Migrationsempfehlungen über dialogbasierte Schnittstellen.
Einschränkungen
LLMs haben jedoch auch erhebliche Einschränkungen:
- Nicht-deterministisch: Die Ergebnisse sind nicht garantiert wiederholbar, was für produktive CI/CD-Pipelines ein Problem darstellt.
- Black-Box-Natur: Begrenzte Transparenz bei der Entscheidungsfindung und den Sicherheitsgarantien.
- Prompt-Abhängigkeit: Qualität und Tiefe hängen stark davon ab, wie der Benutzer die Anfrage formuliert. Ohne den richtigen Kontext können LLMs falsche oder unvollständige Ergebnisse liefern.
Ausblick
Kombiniert mit regelbasierten Tools wie OpenRewrite und Analyse-Frameworks wie Konveyor könnten LLMs als „kreative Ergänzung“ dienen für:
- Das Identifizieren semantischer Muster
- Das Generieren benutzerdefinierter Rewrite-Recipes
- Das Automatisieren von Pull-Request-Beschreibungen, Migrationsdokumentationen und Code-Kommentaren
Eine hybride Lösung aus Reproduzierbarkeit und kontextuellem Verständnis zeichnet sich als vielversprechender Ansatz ab. Konveyor erforscht diese Richtung bereits mit seiner Komponente Konveyor AI, die LLM-Funktionen in den Migrationsprozess integriert.
Fazit: Automatisierung als Schlüssel zu skalierbarer Migration
Die Migration in die Cloud erfordert ein starkes Architekturverständnis, hohe Codequalität und präzise Planung. Sie ist selten ein linearer Prozess – vielmehr ist sie ein iterativer Zyklus aus Analyse, Entscheidungsfindung, Anpassung und Validierung. Hier spielen Open-Source-Tools wie Konveyor und OpenRewrite ihren vollen Wert aus:
- Konveyor bietet strukturierte, reproduzierbare Analysen zur Steuerung von Planung und Entscheidungsfindung – von der Bewertung der Cloud-Readiness über die Erkennung von Technologien bis hin zur Risikobewertung.
- OpenRewrite wendet regelbasierte, semantisch präzise Refactorings an und ermöglicht so nachvollziehbare, CI/CD-konforme Codetransformationen mit minimalem manuellem Aufwand.
Zusammen bilden sie ein komplementäres Toolset: Analyse und Ausführung, Strategie und Umsetzung, Transparenz und Automatisierung. Für Organisationen, die ihre Anwendungslandschaften zukunftssicher machen wollen, bieten diese Tools einen skalierbaren, offenen und gut integrierten Weg in die Cloud – frei von Black-Box-Verhalten, aber mit klaren Regeln, hoher Wiederverwendbarkeit und wachsender Community-Unterstützung.
Die Zukunft liegt jedoch in der Kombination: Konveyor und OpenRewrite für die strukturierte Migration, LLMs für kreative Erweiterungen – eingebettet in DevOps-Prozesse und cloud-native Prinzipien. So wird die Migration nicht zu einem einmaligen Kraftakt, sondern zu einem kontinuierlichen Modernisierungsprozess: skalierbar, nachvollziehbar und automatisiert.
Ein Beitrag von
Markus Zimmermann
ist Software Architect bei der QAware. Er verantwortet als technischer Chefdesigner den Erfolg bei unterschiedlichen Kunden mit Fokus auf Platform Engineering und Cloud Native. Markus hat [...]