Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q
blog-icon Blog

7 Min. Lesezeit

Vom Monolithen in die Cloud: Cloud Migrationen automatisieren

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

typical-obstacles

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.

readiness-levels

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:

  1. 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.
  1. 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.

  2. 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:

  1. Installieren Sie die Kantra-CLI durch Herunterladen von der Kantra Releases-Seite.

  2. 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 
  1. Ü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).

initial-konveyor-analysis

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.

migration-strategies

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.

  1. Fügen Sie die folgende Plugin-Konfiguration zu Ihrer pom.xml unter <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>
  1. 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 [...]