Deployment einer Spring Boot Anwendung in der AWS Cloud mit EC2 & S3

Wenn man nach Spring und Cloud sucht, fällt einem schnell auf, dass diese Kombination kein Wunsch ambitionierter Entwickler mehr ist, sondern schon längst in Spring integriert wurde. Spring Cloud stellt Entwicklern Werkzeuge zur Verfügung, mit denen das Aufsetzen und Verwalten verteilter Systeme und typischer Anwendungsfälle vereinfacht werden soll. Hierfür hat Spring schon eine Vielzahl an Funktionen für verschiedene Cloud Dienste wie Azure und Amazon Web Services bereitgestellt. Heute sehen wir uns an, wie man eine Spring Boot Anwendung in die AWS Cloud deployen kann und wie anfängerfreundlich sich das ganze gestaltet.

Bei meiner Recherche habe ich mehrere Wege gefunden, mein Vorhaben durchzuführen. Da ich die Vor- und Nachteile nicht auf Anhieb erblicken konnte, habe ich mich spontan für den Weg über AWS EC2 und S3 entschieden.

Ausgangslage ist ein Zugang zur AWS Management Konsole (ich nutze selbst nur die kostenlose Version) und ein kleines Spring Boot Projekt mit Maven, welches eine einfache REST-Schnittstelle zum Abrufen und Anlegen von Usern bereitstellt. Ein User ist hier eine einfache Entität mit Vorname, Nachname und Alter und wird in einer H2 Datenbank gespeichert. Die Anwendung ist mit Absicht einfach gehalten, da es hier nur um das Deployment geht.

Zuallererst führen wir einen Maven Build durch, sodass wir eine JAR-Datei unserer Anwendung erhalten. Dafür erstellen wir zunächst ein S3-Bucket über die Managementkonsole mit den standardmäßigen Einstellungen und laden dort unsere JAR-Datei hoch, ebenfalls mit den Standardeinstellungen. Das Ergebnis sollte dann so aussehen:


Während unsere Datei hochlädt, können wir nebenbei eine EC2 Instanz erstellen. Ich wähle hier das Amazon Linux AMI Image, da hier Java bereits vorinstalliert ist. Beachtet, falls ihr euch für ein anderes Image entscheiden solltet (z.B. Ubuntu), dass Java dort eventuell erst noch installiert werden muss. Als Instanztyp wähle ich t2.micro, da mir dieser als kostenlos angezeigt wird. Nun erhalte ich gleich die erste Warnung. „Sicherheit ihrer Instances erhöhen. Ihre Sicherheitsgruppe ist für alle offen.“ Da es sich hier um eine reine Testanwendung handelt, soll mir das an dieser Stelle egal sein.

In einem realen Projekt ist hier noch eine geeignete Sicherheitsgruppe auszuwählen. Weiterklicken und für die Instanz ein neues Schlüsselpaar erstellen (ihr werdet dann aufgefordert eine PEM-Datei herunterzuladen, gut aufheben!). Ich habe nun erfolgreich eine EC2 Instanz erstellt. Nun müssen wir uns zu dieser EC2 Instanz verbinden. Hierfür gibt es viele Wege. Ich habe mich dazu entschieden die Git Bash und SSH zu nutzen. Wenn ihr euch im EC2-Dashboard eure EC2 Instanz anzeigen lasst, findet ihr den Button „Verbinden“. Hier findet ihr den SSH Befehl, um euch über die Bash mit eurer Instanz zu verbinden. Bei mir lautet dieser:

ssh -i "demokeypair.pem" ec2-user@ec2-18-196-127-6.eu-central-1.compute.amazonaws.com

Wichtig ist die, Bash in dem Ordner zu öffnen, in dem eure PEM-Datei liegt. Dann müsst ihr nur noch den Befehl eingeben und seid direkt verbunden.

Als Nächstes muss die JAR-Datei aus dem S3-Bucket in die EC2-Instanz geladen werden. Hierfür geht ihr über die Managementkonsole in den zuvor erstellten S3-Bucket und klickt auf die Datei, die ihr hochgeladen habt. Dort kopiert ihr die Objekt-URL und ladet mit dem Befehl wget die Datei in die EC2- Instanz. Also z.B.:

wget https://springcloudexample.s3-us-west-2.amazonaws.com/simpleapp-0.0.1-SNAPSHOT.jar

Beim ersten Mal bekomme ich hier folgende Fehlermeldung. Was habe ich falsch gemacht?

HTTP request sent, awaiting response... 403 Forbidden

Meine erste Überlegung ist, dass irgendeine Einstellung des S3-Buckets nicht public ist. Auf der Suche in der S3-Datei, stoße ich unter Objekt-Aktionen auf den Punkt „öffentlich zugänglich machen“ und sehe die Meldung: „Der öffentliche Zugriff wird blockiert, da Einstellungen für das Blockieren des öffentlichen Zugriffs für diesen Bucket aktiviert sind.“ Ich klicke auf den vorgeschlagenen Link zu den „Einstellungen ‘Öffentlichen Zugriff beschränken’ für diesen Bucket“ und sehe auch gleich den Status „Bucket und Objekte sind nicht öffentlich.“ Unter dem Bearbeiten Button im „Öffentlichen Zugriff beschränken“-Feld, können wir die Einstellung für das Blockieren des gesamten öffentlichen Zugriffs wieder entfernen.

Speichert die Einstellung und klickt nun noch einmal auf öffentlich zugänglich machen. Nachdem ihr eine grüne Bestätigungsmeldung bekommen habt, sollte das Herunterladen klappen.

Diese Einstellung stellt für mein Demo-Projekt kein Problem dar, ist aber für ein reales Projekt nicht empfehlenswert. Hier sollte man sich mit den entsprechenden Credentials richtig authentifizieren, was aber nicht Thema dieses Blog-Posts ist.

Wenn ihr erneut versucht, die JAR-Datei aus S3 herunterzuladen, könnt ihr mit dem Bash-Befehl “ls” auch noch einmal überprüfen, ob eure JAR-Datei nun heruntergeladen wurde.

Ausführen können wir das Ganze nun mit:

java -jar simpleapp-0.0.1-SNAPSHOT.jar

Und sehen wie unsere Spring Boot Anwendung in Kürze über die Cloud hochfährt. Wir sehen auch, dass ein Tomcat-Server auf Port 8080 hochgefahren wurde. Um euch mit der EC2-Instanz verbinden zu können, wählt im EC2-Dashboard eure Instanz aus und sucht nach der URL unter dem Punkt “Öffentlicher IPv4-DNS”. Die Url sollte ungefähr so aussehen:

ec2-18-196-127-6.eu-central-1.compute.amazonaws.com

Hier muss noch der Port 8080 und die richtigen Endpunkte angefügt werden. Diese lauten bei mir „/user“ mit Post, um einen User anzulegen und „/user/all“ um sich alle User anzuzeigen.

Über einen Curl mit einem Post Befehl kann ich z. B. ein paar User anlegen.

Der Curl-Befehl könnte z.B. so aussehen:

curl -X POST -H "Content-Type: application/json" -d '{"id": 1, "name": "Dave Develop", "age":20}' http://ec2-18-196-127-6.eu-central-1.compute.amazonaws.com:8080/user

Das war’s auch schon. Wir haben nun eine einfache Spring Boot-Anwendung erfolgreich in die AWS Cloud deployt.

Hinweis: Wird die Anwendung bei euch nicht geladen? Keine Sorge, bei mir zunächst auch nicht, denn ich habe noch eine wichtige Sache vergessen. Die standardmäßig eingestellte Sicherheitsgruppe erlaubt für eingehende Port-Bereiche nur den Port 22. Unsere Anwendung läuft aber auf dem Port 8080. Daher müssen wir hier noch eine Regel hinzufügen, die den Port 8080 für eingehenden Datenverkehr erlaubt.

Hinweis 2: Wenn wir unsere Bash nun schließen, hört die Anwendung auch auf zu laufen. Das scheint erstmal logisch, ist aber wohl nicht der Sinn, eine Anwendung in der Cloud zu deployen, denn man möchte ja, dass AWS die Anwendung immer zur Verfügung stellt, und zwar ohne uns. Ansonsten könnten wir auch einfach selbst wieder lokal Server spielen. Was wir brauchen ist also eine Möglichkeit, die JAR-Datei automatisch beim Starten der EC2-Instanz mit hochzufahren. Dies ist eigentlich Stoff für einen weiteren Blog-Post, jedoch sei hier als Hinweis gesagt, dass hier der “java -jar..”-Befehl mittels der User-Data unter EC2 als Bash-Skript eingefügt werden kann, und dann beim Start der Instanz ausgeführt wird.

Fazit

Im Grunde war es nicht schwer, die Anwendung zu deployen, wobei man sich als Anfänger mit den passenden Security Groups und Access Rights nicht wirklich gut auskennt und hier noch etwas Zeit benötigt, sich in diese Themengebiete einzuarbeiten. Ein weiterer Ausblick wäre hier noch die Verbindung mit einer Datenbank über Amazon RDS. In der AWS Doku findet sich ebenfalls ein Vorgehen, Elastic Beanstalk für das Deployment zu nutzen. Elastic Beanstalk wird als Managed Service für das Deployment von Web Applications und Services beworben. Klingt so weit ganz passend für unser Vorhaben, und das Deployment funktioniert hier auch ähnlich, indem man seine JAR-Datei in Elastic Beanstalk hochlädt. Jedoch startet Elastic Beanstalk im Hintergrund selbst auch eine EC2-Instanz und noch einige andere Dienste automatisch. Dies kann für komplexere Web-Anwendungen durchaus die bessere Methode sein, da man sich um viele Dienste, die im Hintergrund gestartet werden, nicht selbst kümmern muss. Es kann aber auch gerade für Anfänger hilfreich sein, einmal die einzelnen Dienste manuell auszuführen, um ein Gefühl dafür zu bekommen, was dort im Hintergrund eigentlich abläuft und welche Einstellungen noch alle möglich sind, um seine Anwendung weiter zu spezifizieren.

Views All Time
836
Views Today
5
Short URL for this post: https://blog.oio.de/Hg64S
This entry was posted in Java Runtimes - VM, Appserver & Cloud and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *