DevOps Projekt 2: Lift & Shift – von lokalem Multi-VM Setup zu AWS
Weiterentwicklung meines lokalen Projekts (Vagrant Multi-VM) zu einer
Lift-&-Shift Migration auf AWS.
Fokus: gleiche Anwendung / gleiche Rollen, aber Cloud-Infrastruktur mit
EC2, S3, Application Load Balancer, Route 53, ACM und Auto Scaling.
Wichtig:
Dieses Projekt zeigt die Entwicklung von Local Automation (Vagrant) zu einer
Cloud-Migration (AWS) – inklusive Security, DNS, HTTPS, Artefakt-Management und Skalierung.
1. Projektziel
Ziel war es, den bestehenden lokalen Multi-Service-Stack (Nginx → Tomcat → DB/Cache/Queue)
als Lift & Shift nach AWS zu übertragen.
Dabei bleibt die Anwendung (WAR, Ports, Services) konzeptionell gleich – aber die Infrastruktur wird cloud-ready:
Stabiler Entry Point: HTTPS über Application Load Balancer
Reproduzierbares Deployment: Artefakt zentral in S3
Security-by-Design: getrennte Security Groups + IAM Roles
Skalierung: Auto Scaling Group für Tomcat Instances
2. Architektur-Übersicht: Lokal → AWS
Links: lokales Multi-VM Setup (Vagrant). Rechts: AWS Architektur (ALB + EC2 + S3 + DNS + Auto Scaling).
Hinweis:
Lokal war Nginx der Entry Point. In AWS übernimmt diese Rolle der Application Load Balancer (HTTPS),
während Tomcat horizontal skaliert werden kann (ASG). Artefakte liegen zentral in S3.
3. Ausführungsablauf (AWS) – Visuelles Schema
Dieses Diagramm entspricht dem realen Implementierungsablauf – inklusive des Artefakt-Flows
Build → S3 → EC2.
Kernidee:
Der Ablauf trennt klar zwischen Build, Artefakt-Speicherung und Runtime
und folgt damit DevOps- und AWS-Best-Practices.
4. Login in den AWS Account
- Ziel:
Zugriff auf die AWS-Konsole als "Root user", um Cloud-Infrastruktur zu erstellen und zu verwalten. (https://aws.amazon.com/de/console/)
Warum?
Alle AWS-Ressourcen werden über die Konsole oder API erstellt und administriert.
Das ist der Pflicht-Startpunkt für jede Cloud-Migration.
AWS Management Console – erfolgreicher Login mit Zugriff auf das EC2 Dashboard
(Region: N. Virginia).
5 Key Pair erstellen
- Ziel:
SSH-Key als ".pem-Datei" für den sicheren Zugriff auf EC2-Instanzen über Git Bash.
Hinweis: Diese SSH-Verbindung wird später verwendet, um sich direkt mit der EC2-Instanz zu verbinden.
Dabei ist ec2-user der standardmäßige Linux-Benutzer auf Amazon-Linux-Instanzen
und <PUBLIC_IP> die öffentliche IP-Adresse der EC2, über die sie aus dem Internet erreichbar ist.
All traffic → SG-Backend
– Interne Kommunikation zwischen alle Backend-Services
- Kein Public Access
- Backend ist isoliert und abgesichert
Hinweis: Die Port- und Host-Konfiguration aller Backend-Services
(MySQL, Memcached, RabbitMQ) befindet sich zentral in
src/main/resources/application.properties.
7. EC2-Instanzen mit User Data (Bash) starten
- Ziel:
EC2-Instanzen so starten, dass sie sich beim ersten Boot automatisch konfigurieren.
- Wie viele EC2 und warum?
Rolle EC2 Warum
Tomcat 1 Anwendung
MySQL 1 Daten
Memcached 1 Cache
RabbitMQ 1 Messaging
Gleiche Aufteilung wie im lokalen Vagrant-Projekt.
- Wie wird eine EC2 konkret erstellt?
Bevor wir EC2-Instanzen herstellen und starten, bereiten wir den Code und die Provisioning-Dateien sauber vor.
So bleiben Infrastruktur und Applikationskonfiguration versioniert, reproduzierbar und auditierbar.
Prerequisite:
Für die AWS-Migration arbeiten wir in einer eigenen Git-Branch awsliftandshift.
Dadurch bleiben das lokale Vagrant-Setup und die AWS-Änderungen klar getrennt.
Repository klonen und in VS Code öffnen. userdata/ in Projektordner anlegen, der alle Dateien(Konfiguration + Service-Skripte) enthält, die beim EC2-Start genutzt werden.
Diese Skripte existieren, um EC2-Instanzen automatisch beim ersten Boot zu provisionieren (User Data). Dadurch entfällt manuelle Konfiguration per SSH und das Setup wird reproduzierbar
git clone <repo-url>
cd project-root
code .
application.properties: Zentrale App-Konfiguration (DB/Cache/Queue Hosts & Ports).
In AWS bevorzugt über Private DNS (Route 53) statt fester IPs.
al2023rmq.repo: Diese Datei wird in rabbitmq.sh aufgeruft und definiert offizielle RabbitMQ- und Erlang-Repositories, um eine kompatible, sichere und stabile Installation von RabbitMQ auf Amazon Linux zu gewährleisten.
mysql.sh: Installiert & konfiguriert die Datenbank (User/Grants/Schema) –
damit die App sofort persistente Daten speichern kann.
memcache.sh: Installiert Memcached und startet den Service –
für schnelle Sessions/Cache, weniger DB-Last.
rabbitmq.sh: Installiert RabbitMQ, richtet User/Permissions ein –
für asynchrone Kommunikation (Queue).
tomcat_ubuntu.sh: Installiert Java + Tomcat und aktiviert den Service –
vorbereitet für das Deployment des ROOT.war.
Jetzt Herstellen der EC2-Instanzen mit Konfiguration in AWS(Launch instances) :
Die folgende Tabelle zeigt die exakten Einstellungen, mit denen die vier EC2-Instanzen erstellt werden
(Name, AMI, Typ, Key Pair, Security Group und das passende User-Data-Skript).
Instance Name
AMI
Instance Type
Key Pair
Network Settings (Security Group)
User Data
profile-db01
Amazon Linux
t3.micro
profile-prod-key.pem
SG-Backend
backend.sh
profile-mc01
Amazon Linux
t3.micro
profile-prod-key.pem
SG-Backend
memcache.sh
profile-rmq01
Amazon Linux
t3.micro
profile-prod-key.pem
SG-Backend
rabbitmq.sh
profile-app01
Ubuntu 24.04
t3.micro
profile-prod-key.pem
SG-Tomcat
tomcat_ubuntu.sh
Hinweis: Die Backend-Instanzen (db01, mc01, rmq01) liegen bewusst in
SG-Backend (kein Public Access). Die Applikationsinstanz app01 nutzt SG-Tomcat,
damit nur der Load Balancer (und Admin-SSH) Zugriff erhält. profile-app01 auf Ubuntu 24, weil Tomcat + Java + die Applikation unter Ubuntu stabiler sind.
Übersicht der laufenden EC2-Instanzen (profile-app01, profile-db01, profile-mc01, profile-rmq01) –
jede Instanz repräsentiert einen dedizierten Service der Anwendung.
wichtig: dann in Git Bash:
ssh -i project-prod-key.pem ec2-user@<PUBLIC_IP>
sudo -i
systemctl status "service-name"
für profile-app01 Ec2 wird ec2-user als ubuntu ersetzt
Ergebnis:
EC2-Instanzen sind „ready“
Java ist installiert
Tomcat läuft bereits
Kein manuelles Setup nach SSH nötig
8. IPs zu Name Mapping mit Route 53
- Ziel:
IPs durch interne DNS-Namen ersetzen.
- Warum Route 53?
IP-Adressen von EC2-Instanzen können sich ändern (z. B. bei Neustarts).
Durch Route 53 werden stabile DNS-Namen verwendet, die:
die Konfiguration wartbarer machen
Änderungen an IPs transparent abfangen
Abhängigkeiten zwischen Services entkoppeln
– In Route 53 "Private Hosted Zone" herstellen
Private Zone, an das VPC gebunden:
Domain name: myapp.internal
- Erstellte Records:
Name Zeigt auf
db01.myapp.internal MySQL privates IP
mc01.myapp.internal Memcached privates IP
rmq01.myapp.internal RabbitMQ privates IP
Hinweis: Hier ist Route 53 für tomcat(app01) nicht nötig, da es Load Balancer verwendet wird.
In Git Bash EC2-Instanzen laufen lassen und Command:
ping -c 4 db01.myapp.internal
Ergebnis:
kommuniziert über Namen statt IPs – robuster, sauberer.
9. Anwendung aus Source Code builden
- Ziel:
Java-Quellcode kompilieren und ein deploybares Artefakt erzeugen (ROOT.war).
- Wo wird dieser Schritt ausgeführt?
Auf PC (lokal), nicht auf AWS
Git Bash / Terminal
VS Code offen im Projekt
Hinweis: Keine EC2 ist bei diesem Schritt beteiligt.
- Warum so?
Build hängt nicht von AWS-Infrastruktur ab
Schneller und kontrollierbarer
Klare Trennung: Build → lokal und Run → Cloud
Der Build erfolgt lokal. Das WAR wird in ein S3-Bucket in AWS hochgeladen (IAM Access Keys) und von der Tomcat-EC2
anschließend per IAM Role sicher aus S3 heruntergeladen.
- AWS Konfiguration
S3 Bucket in AWS herstellen
IAM user mit S3FullAccess herstellen dann ein "acces key" generieren
IAM Role mit S3FullAccess herstellen dann diese Role mit EC2 (Tomcat Server) verbinden
cd profile
mvn install # Build → erzeugt das WAR im target/ Ordner
aws configure # AWS CLI: IAM Access Key/Secret Key konfigurieren
aws s3 cp target/profile-v2.war s3://BUCKET-NAME/ # Artefakt nach S3 hochladen
aws s3 ls s3://BUCKET-NAME/ # Prüfen, ob profile-v2.war vorhanden ist
Teil B – Auf AWS (Tomcat EC2): Download + Deployment
# 1) Verbindung zur Tomcat-EC2 (app01)
ssh -i project-prod-key.pem ubuntu@PUBLIC_IP_TOMCAT
sudo -i
# 2) AWS CLI installieren (nur falls nicht vorhanden)
snap install aws-cli --classic
# 3) Artefakt von S3 holen
aws s3 cp s3://BUCKET-NAME/profile-v2.war /tmp/
# 4) Deployment auf Tomcat 10
systemctl daemon-reload
systemctl stop tomcat10
ls /var/lib/tomcat10/webapps # Default Apps prüfen
rm -rf /var/lib/tomcat10/webapps/ROOT # Default ROOT entfernen
cp /tmp/profile-v2.war /var/lib/tomcat10/webapps/ROOT.war # WAR als ROOT deployen
systemctl start tomcat10
# 5) Quick Check lokal auf der EC2
curl -I http://localhost:8080/
Erwartetes Ergebnis: HTTP/1.1 200 OK
Hinweis:ROOT.war wird automatisch nach ROOT/ entpackt.
Dadurch ist die App direkt unter / erreichbar .
10. Application Load Balancer Setup mit HTTPS (ACM)
Ziel
Der Load Balancer ist der zentrale Einstiegspunkt (Single Entry Point) für alle Benutzeranfragen an die Anwendung und die Absicherung des Benutzerzugriffs mit HTTPS.
Warum?
Benutzer greifen nicht direkt auf Tomcat-Instanzen zu
Der Load Balancer übernimmt Öffentlichen Zugriff und Weiterleitung der Requests
Tomcat bleibt intern und geschützt
Der Load Balancer terminiert TLS/HTTPS
User (HTTPS mit Zertifikat von ACM)
↓
ALB (TLS Termination)
↓
Tomcat EC2 (HTTP)
Werkzeuge & Setup für den Load Balancer
In diesem Schritt wird der Load Balancer mit HTTPS abgesichert und
mit der Tomcat-Anwendung verbunden.
Domain-Validierung über DNS (CNAME-Record) bei GoDaddy
Target Group für Tomcat (app01) herstellen
Target Type: Instances
Protocol: HTTP
Port: 8080
Health Check: HTTP auf Port 8080Override
Application Load Balancer (ALB) herstellen
Listener für HTTP (80) und HTTPS (443)
Verwendung der Load Balancer Security Group
Zertifikat-Quelle: AWS ACM
ALB DNS-Name wird als CNAME bei GoDaddy hinterlegt
Health Check
Der Status der Tomcat-Instanzen wird über die Target Group geprüft.
Der Status muss Healthy sein.
Ergebnis im Browser
Aufruf über den Load Balancer DNS-Namen:
Anwendung startet auf Port 8080 → nicht sicher (HTTP)
Aufruf über die Domain (GoDaddy):
Anwendung erreichbar über HTTPS → sichere Verbindung
GoDaddy steuert nur das DNS-Routing (wohin die Domain zeigt). Das TLS-Zertifikat wird in AWS über
ACMALB genutzt (HTTPS).
Merksatz:
GoDaddy sagt wohin der Traffic geht (DNS). ACM/ALB sorgen dafür, dass der Traffic verschlüsselt ankommt (HTTPS).
11. Auto Scaling Group (Tomcat)
- Ziele
Hohe Verfügbarkeit (Mehrere Tomcat-Instanzen)
Automatische Skalierbarkeit
Load Balancer leitet Traffic nur zu gesunden Instanzen
- Funktionsweise
Application Load Balancer verteilt den Traffic.
Auto Scaling Group entscheidet, wie viele Instanzen existieren.
Health Checks ersetzen fehlerhafte Instanzen automatisch.
User
↓
ALB
↓
Auto Scaling Group
├─ Tomcat EC2 #1
├─ Tomcat EC2 #2
└─ Tomcat EC2 #3
- Werkzeuge & Setup für die Auto Scaling Group
Für die Einrichtung einer Auto Scaling Group werden drei zentrale Komponenten benötigt.
Diese sorgen dafür, dass Tomcat-Instanzen automatisch erstellt, ersetzt und skaliert werden können.
1) AMI (Amazon Machine Image)
Dient als Vorlage für neue Tomcat-Instanzen.
Erstellung eines Images (AMI) aus der bestehenden EC2 app01 (Tomcat)
Das AMI enthält:
Installiertes Betriebssystem
Java & Tomcat
Deployte Anwendung
2) Launch Template
Definiert, wie neue EC2-Instanzen gestartet werden.
Erstellung eines Launch Templates basierend auf dem erzeugten AMI
Verwendete Einstellungen:
Security Group: Tomcat Security Group
Key Pair: Projekt-Key
IAM Role: Zugriff auf S3 (Artefakte)
Tags: project=profile, role=tomcat
3) Auto Scaling Group (ASG)
Steuert die Anzahl und den Zustand der Tomcat-Instanzen.
Erstellung der Auto Scaling Group mit dem Launch Template
Anbindung an den Application Load Balancer über die Tomcat Target Group
Health Checks über den Load Balancer
Vorteil:
Unhealthy Instanzen werden automatisch entfernt
Neue Instanzen werden automatisch erstellt
Ergebnis:
Die Anwendung bleibt hochverfügbar.
Bei Lastspitzen oder Instanz-Ausfällen reagiert AWS automatisch –
ohne manuelles Eingreifen.
12. Fazit
Die Lift-&-Shift-Strategie ( Build(lokal) → S3(AWS) → EC2(AWS) ) ermöglicht eine schnelle Migration
ohne Code-Änderungen.
Sie schafft eine stabile Basis, auf der spätere Optimierungen
sicher aufgebaut werden können.
✔ Schnelle Migration bestehender Anwendungen
✔ Minimales Risiko
✔ Gleiche Architektur
Aufbauend auf diesem Projekt sind Cloud-Native-Weiterentwicklungen geplant.