Dieser Guide ist dein Spickzettel, um diese typischen Fehler zu vermeiden und schneller zum Serverless-Profi zu werden. Die Muster dahinter sind frustrierend ähnlich. Deshalb hat Lena von bespinian diesen Blogpost zusammengestellt: Betrachte jedes Level als Lektion – als Fehler, den du nicht selbst machen musst. Wenn du tiefer einsteigen und die Learnings selbst anwenden möchtest, folge dem Open-Source-Serverless Workshop von bespinian. Sowohl dieser Blogpost als auch der Workshop verwenden AWS Lambda, die Learnings lassen sich aber auf jede Function-as-a-Service-Plattform (FaaS) übertragen. Also, los geht’s.
Level 0: Das ist einfach!
⚠️ Fehler: Noch keiner
Zum Start brauchen wir unsere erste Function. Viele Projekte stürzen sich in komplexe Architekturen, ohne die Grundlagen zu verstehen – das führt zu Verwirrung und unnötigem Aufwand. In diesem Level geht es darum, die grundlegende Mechanik von Serverless zu entmystifizieren: wie man eine Function erstellt, ihre Runtime konfiguriert und Parameter über Umgebungsvariablen übergibt. Ausserdem solltest du dich mit dem Berechtigungsmodell deines Cloud-Providers vertraut machen, einem Grundpfeiler sicherer Serverless-Anwendungen. Mit einem HTTP-Trigger über ein API Gateway wird unsere Function zu einem über das Web erreichbaren Service – greifbar und interaktiv.
✅ Starte so einfach und klein wie möglich und baue von dort aus weiter.
Level 1: Loggen!
⚠️ Fehler: Kein Structured Logging
Unsere erste Function ist deployt, aber wir haben keine Ahnung, was sie tut und ob sie erfolgreich ist. Wenn etwas schiefgeht, ist es sehr schwierig, den Fehler zu finden und zu untersuchen. Viele Serverless-Projekte leiden unter mangelnder Observability, was die Fehlersuche zum Albtraum macht. Mit Structured Logging (z. B. im JSON-Format) erhalten wir Logs, die wir abfragen können und die uns gezielte Einblicke geben, was unsere Function tut. So wissen wir, ob sie erfolgreich ist oder fehlschlägt, und bekommen Kontext dazu, was schiefgelaufen ist, wenn etwas nicht wie erwartet läuft. Eine solche Logzeile könnte so aussehen:
{
"correlationId": "9ac54d82-75e0-4f0d-ae3c-e84ca400b3bd",
"requestId": "58d9c96e-ae9f-43db-a353-c48e7a70bfa8",
"commitHash": "9d9154e",
"level": "INFO",
"requestPath": "/users/1",
"requestMethod": "GET",
"responseCode": 200,
"responseBody": "All good"
}
✅ Warte nicht auf Probleme in der Produktion, um Structured Logging einzuführen.
Level 2: Tracen!
⚠️ Fehler: Kein Distributed Tracing
Je grösser deine Serverless-Anwendungen werden, desto wichtiger wird es, den Weg der Requests zu verstehen. Distributed Tracing liefert wertvolle Einblicke in Performance-Engpässe und Fehler. Die meisten Cloud-Provider bieten umfassende Tools, mit denen du mit wenigen Zeilen Code Tracing-IDs hinzufügen und sogar HTTP-Aufrufe und andere Function-Aufrufe tracen kannst. Tracing ist deshalb meist günstig umzusetzen, während der Nutzen gross ist. Eine «low-hanging fruit», die du dir nicht entgehen lassen solltest.
✅ Aktiviere Distributed Tracing für alle deine Functions.
Level 3: Timeouts im Griff!
⚠️ Fehler: Timeouts werden nicht sauber behandelt
Functions laufen innerhalb fester Zeitlimits, deshalb ist es wichtig, Timeouts sauber zu behandeln. Unbehandelte Timeouts können zu unerwartetem Verhalten und inkonsistenten Daten führen. Unsere Functions sollten sauber und vorhersehbar enden, auch wenn sie sich ihrem Zeitlimit nähern. Dafür überwachst du einfach die verbleibende Ausführungszeit und brichst lang laufende Operationen rechtzeitig ab. So bleibt genug Zeit für ein sauberes Aufräumen oder für Teilergebnisse – und für eine reibungslose, zuverlässige User Experience.
✅ Lass nicht zu, dass Timeouts Chaos in deiner Anwendung verursachen.
Level 4: Optimierte Cold Starts!
⚠️ Fehler: Cold-Start-Performance wird ignoriert
Cold Starts – die anfängliche Latenz, wenn eine Lambda Function nach einer Zeit der Inaktivität aufgerufen wird – können die Performance beeinträchtigen. Bei latenzkritischen Anwendungen merken Nutzer:innen schon wenige zusätzliche Millisekunden. Dieses Level zeigt Techniken, um Cold Starts zu verkürzen, zum Beispiel indem Initialisierungscode ausserhalb des Handlers platziert wird. Wenn wir den Start unserer Function optimieren, reagiert sie schneller und die User Experience verbessert sich insgesamt.
✅ Optimiere früh für Cold Starts, um spätere Performance-Engpässe zu vermeiden.
Level 5: Entkoppelt!
⚠️ Fehler: Enge Kopplung
Je grösser deine Serverless-Anwendungen werden, desto wichtiger wird asynchrone Kommunikation. Ohne sie sind Services oft eng gekoppelt: Fällt einer aus, kann das einen Dominoeffekt im ganzen System auslösen. In diesem Level lernst du Amazon SQS kennen, einen einfachen, aber leistungsstarken Message-Queuing-Service. Stell ihn dir als Wartezimmer für Nachrichten vor: Deine Function legt eine Nachricht ab und kümmert sich um anderes, während eine andere Function sie später abholt, sobald sie bereit ist. Diese Entkopplung sorgt für skalierbarere und resilientere Architekturen und macht deine Anwendung deutlich robuster.
✅ Nutze Message Queues wie SQS, um Services zu entkoppeln und ein resilienteres System zu bauen.
Level 6: Infrastructure as Code!
⚠️ Fehler: Manuelles Infrastruktur-Management
Cloud-Ressourcen von Hand zu verwalten ist langsam, inkonsistent und sehr fehleranfällig – ein Rezept für Chaos, gerade wenn deine Anwendung wächst. In diesem Level geht es um Infrastructure as Code (IaC) mit einem Tool wie Terraform. Wenn du deine Serverless Functions und ihre Abhängigkeiten in einer Konfigurationsdatei definierst, kannst du deine Infrastruktur wie jeden anderen Code behandeln. Das bedeutet wiederholbare, versionierte Deployments, die in allen Umgebungen konsistent sind.
✅ Hör auf, in der Konsole herumzuklicken, und verwalte deine Infrastruktur mit Code.
Level 7: Alles testen!
⚠️ Fehler: Fehlende Tests
Ohne Sicherheitsnetz zu entwickeln ist riskant. Ungetesteter Code ist ein Desaster mit Ansage und kann zu Bugs, unerwartetem Verhalten und Ausfällen in der Produktion führen. Dieses Level widmet sich der wichtigen Praxis von Unit Tests und der lokalen Ausführung deiner Functions. Wenn du Tests schreibst, die das Verhalten deines Codes prüfen, und sie lokal ausführst, findest du Fehler früh und stellst sicher, dass deine Functions zuverlässig laufen, bevor sie in die Produktion gehen.
✅ Hoffe nicht nur, dass dein Code funktioniert – teste ihn, um sicher zu sein.
Level 8: Absichern!
⚠️ Fehler: Zu weit gefasste Berechtigungen
Einer Function mehr Berechtigungen zu geben, als sie braucht, ist, als würdest du einen Generalschlüssel für dein ganzes Haus verteilen. Das schafft eine massive Sicherheitslücke. In diesem Level geht es um das Prinzip der minimalen Rechte (Least Privilege): Deine Functions erhalten nur die absolut nötigen Berechtigungen für ihre Aufgabe. Wenn du Zugriffe sorgfältig definierst und einschränkst, verringerst du den möglichen Schaden bei einem Sicherheitsvorfall deutlich und stärkst die Sicherheit deiner Anwendung insgesamt.
✅ Setze das Prinzip der minimalen Rechte um, um deine Serverless Functions abzusichern.
Level 9: Der schrittweise Rollout!
⚠️ Fehler: Riskante Deployments
Eine neue Version deiner Anwendung auf einen Schlag für 100 % deiner Nutzer:innen auszurollen, ist ein riskantes Spiel. Gibt es ein Problem, spüren es alle sofort. Dieses Level stellt einen sichereren Ansatz vor: Canary Deployments. Mit einem Service wie AWS CodeDeploy kannst du eine neue Version automatisch zuerst für einen kleinen Teil deiner Nutzer:innen freigeben. Läuft die neue Version gut, rollst du sie schrittweise für alle aus. Wenn nicht, kannst du schnell zurückrollen und die Auswirkungen von Fehlern gering halten.
✅ Minimiere das Deployment-Risiko, indem du Änderungen schrittweise ausrollst.
