Developer-Erfahrungsbericht

Cloud-Native mit AWS Lambda entwickeln

07.10.2022
Von   IDG ExpertenNetzwerk
Andreas Hernitscheck entwirft als Softwarearchitekt komplexe Systeme unter Verwendung von Cloud-Technologien. Als Entwicklungsleiter koordiniert er den Lebenszyklus von Software und führt Teams zum Erfolg. Das breite Wissen über verschiedene Technologien erweitert er seit 1988 bis heute ständig, um optimal zu beraten und gute Lösungen zu schaffen.
Eine Cloud-Native-Applikation mit AWS Lambda entwickeln? Ein Erfahrungsbericht.
Lesen Sie, wie sich das Cloud-Native-Entwicklungserlebnis mit AWS Lambda gestaltet.
Lesen Sie, wie sich das Cloud-Native-Entwicklungserlebnis mit AWS Lambda gestaltet.
Foto: Gorodenkoff - shutterstock.com

Geht es um die Definition von Cloud-Native, gehen die Meinungen auseinander. Viele sehen bereits eine virtuelle Infrastruktur in einem Rechenzentrum, die virtuelle Maschinen dynamisch skaliert, als Cloud-Native an. Dabei können beispielsweise Microservices durch Docker Container bereitgestellt werden und ein Orchestrator wie ECS oder Kubernetes verteilt diese dann je nach Auslastung auf der Infrastruktur. Das sehe ich noch nicht als Cloud-Native, sondern bezeichne dies einfach als skalierungsfähige Virtualisierung.

Den Begriff Native nehme ich hier noch wörtlicher und entferne die eigene Virtualisierung in Docker-Containern aus der Umsetzung. Das bedeutet: Ich möchte, dass die unmittelbare Umgebung meines Codes von der Cloud verwaltet wird. AWS ermöglicht das durch die Bereitstellung ihrer Lambda-Umgebung. Desweitern sollen auch Datenbanken nicht mehr selbst verwaltet werden, sondern Alternativen von AWS, die jedoch von AWS voll kontrolliert werden. Also auch hier der Verzicht auf eigene Virtualisierung.

Mein Entwicklungsziel

Es sollte eine Webanwendung werden, die das hundertprozentige Cloud-Native-Konstrukt verwendet. Also keine selbst verwalteten virtuellen Maschinen oder Container. Das Frontend soll aus HTML und CSS bestehen. Dazu nutzte ich das Framework Vue.js, das klein, aber leistungsstark ist. Als Programmiersprache wählte ich Python. Einfach nur damit es nicht wieder JavaScript ist und ich etwas dazulernen kann.

Die Entwicklungsumgebung

Viele AWS-Verfechter sind der Meinung, dass man Cloud-Native direkt auf AWS entwickeln sollte. Sie haben insofern Recht, dass nur AWS selbst, sich auch wie AWS verhält. Jede Simulation könnte sich theoretisch auch etwas anders verhalten. Nur wie soll man so entwickeln? Es ist schon möglich, dass bei jeder Code-Änderung diese automatisch ausgerollt wird. Wenn dabei auch noch Cloudformation zum Einsatz kommt, was in den Beispielen von AWS auch der typische Ansatz ist, kann dies jedoch leicht zehn Minuten und länger dauern. Dazu würde jeder Entwickler seine eigene AWS-Umgebung benötigen, damit es keine Überschneidungen gibt. Somit sehe ich diesen Weg als eher unpraktikabel an.

Welche Alternative habe ich? Ein Teil der Antwort finde ich in der testgetriebenen Entwicklung (TDD). Das bedeutet, dass ich alle wesentlichen Funktionen und Abläufe, die ich lokal laufen lassen kann, in Tests abbilde. Was die Datenbank betrifft, simuliere ich diese im Speicher. Ist diese Simulation realitätsnah? Ich sollte es herausfinden. Zum Glück gibt es für Python die Bibliothek moto, welche einige AWS-Dienste simulieren kann. Traurigerweise ist dies kein Projekt von AWS selbst, was zeigt, dass AWS gar kein Interesse an einer Simulation ihrer Services hat. Und ja, für meinen Zweck hat moto bezüglich der DynamoDB-Simulation sehr gut funktioniert.

AWS Lambda im Detail

AWS bietet hier einen sehr spannenden Ansatz nach dem Motto: "Programmiere nur Funktionen und wir kümmern uns um den Rest." Das bedeutet, dass man lediglich den Code bereitstellt und keinen Interpreter oder gar ein Docker-Image. Abgerechnet wird dann auch nicht mehr eine virtuelle Maschine, sondern nur die Zeit und der Speicherverbrauch, den diese Funktion während der Ausführung genutzt hat. Dies ist insbesondere für Anwendungen interessant, deren zukünftige Auslastung unklar ist. Falls die Funktionen niemand aufruft, entstehen auch keine Kosten für CPU und RAM. Und im Falle vermehrter Zugriffe, würde AWS diese Funktion entsprechend selbst skalieren.

Diese Flexibilität zahlt man jedoch auch, denn bei einer sehr hohen Nutzung würde wohl beispielsweise eine schnelle Java-Anwendung insgesamt günstiger laufen, sofern man deren Instanzen durch Skalierung anpasst. Auch gibt es leider ein Limit von 1000 parallelen Ausführungen von Lambda-Funktionen. Die Lambda-Funktionen schlafen, bis sie aufgerufen werden und dieser erste Aufruf ist ein Kaltstart, der je nach Code-Größe schon mal zwei Sekunden dauern kann. Sobald die Funktion jedoch aufgerufen wurde, steht sie ohne Kaltstart, sofort für einige Minuten zu Verfügung. Unterstützt werden verschiedene Programmiersprachen, wobei hier JavaScript und Python am leichtesten ihren Weg finden und recht gut dokumentiert wurden.

DynamoDB im Detail

DynamoDB ist eine NoSQL-Datenbank von AWS, die einfache Key-Value-Strukturen speichern kann. Ihr Vorteil ist, dass sie sehr schnell ist, von AWS selbst verwaltet wird, automatisch skaliert und die Kosten nach Verbrauch und Zugriffen berechnet werden. Ihr Nachteil liegt, wie auch bei Lambda, in der schlechten Unterstützung für lokale Entwicklungsumgebungen.

Für mein privates Projekt wählte ich aus Neugier und Kostengründen DynamoDB, obwohl so manche Abfragen, die ich benötigte, eher der Natur einer SQL-fähigen Datenbank entsprechen.

Meine Idealvorstellung

Auch beim Entwickeln möchte man schnell vorwärtskommen. Von AWS wird oft angepriesen, dass man eben nicht viel entwickeln muss, da bereits viele Dienste vorhanden sind und von AWS verwaltet werden. Ja das stimmt! Jedoch gestaltete sich das Entwickeln direkt auf AWS für mich sehr umständlich. Eigentlich möchte ich alles lokal auf meinen Rechner entwickeln und wenn es lokal funktioniert, kopiere ich es, so wie es ist, auf die Cloud und dort soll es das gleiche machen.

Es existiert eine Drittanbieter-Software namens localstack, die ich in einem anderen Projekt mit Microservices verwendet habe. Diese simuliert AWS recht gut und ich kann sie im Grunde auch empfehlen. Jedoch ist damit die Entwicklung von Lambda gar nicht so einfach, da bei AWS verschiedene Dienste ineinandergreifen, um am Ende die Lambda-Funktionalität anzubieten. Also leider auch keine Plug-and-Play-Lösung.

Ziel erreicht?

Ja, ich konnte tatsächlich eine komplette Webanwendung für Cloud-Native entwickeln. Würde ich es wieder so machen? Nein, denn die fehlende Unterstützung, alles lokal zu simulieren macht es sehr schwer, die Anwendung schnell umzusetzen und lokal laufen zu lassen. Um die komplette Anwendung testen zu können, musste ich von meinem lokalen Rechner dann doch die Datenbank sowie andere Dienste direkt in AWS aufrufen.

Cloud-Native mit AWS Lambda: Mein Fazit

In Cloud-Native sehe ich tatsächlich die Zukunft der Softwareentwicklung. Ich musste jedoch auch erkennen, dass es für AWS noch ein langer Weg dahin ist. Insbesondere die praktisch nicht vorhandene Unterstützung einer lokalen Entwicklungsumgebung zum schnellen Umsetzen von Projekten ist für mich ein K.O.-Kriterium. Das Entwickeln rein online scheitert dann am langen Prozess, den Code bereitzustellen.

So hoffe ich, dass sich die Haltung von AWS hierzu ändern wird und entsprechende Werkzeuge entworfen werden, sowie vorhandene Projekte wie moto und localstack direkte Unterstützung finden, damit es Entwickler leicht haben, das Potential schnell nutzen zu können.

Bis dahin empfehle ich weiterhin mit Docker-Images zu arbeiten und Anwendungen als Microservices mit Kotlin oder Java bereitzustellen - sowie auch andere Dienste, die von der Anwendung benötigt werden, als Docker-Images lokal laufen zu lassen. Mit anderen Worten: Warten Sie mit echtem Cloud-Native noch, bis AWS das Programmieren dafür deutlich erleichtert hat. (fm)