Ein serverloses Kontaktformular mit AWS SAM, Lambda und DynamoDB deployen
Bevor du beginnst
- Ein AWS-Konto mit Berechtigungen zum Erstellen von SAM-Stacks, Lambda-Funktionen, DynamoDB-Tabellen, API-Gateway-APIs und SES-Identitaeten
- AWS CLI und SAM CLI installiert und konfiguriert
- Node.js 22 lokal installiert
- Eine verifizierte SES-Sender-Domain oder E-Mail-Adresse
- Eine statische Website, der Sie ein Kontaktformular hinzufuegen moechten (Astro, Next.js, Hugo oder aehnlich)
- Grundlegende Vertrautheit mit TypeScript und AWS CloudFormation
Was du lernen wirst
- Eine vollstaendige Serverless-API mit SAM definieren, einschliesslich API Gateway, Lambda, DynamoDB und SES
- Ein DynamoDB-Single-Table-Schema mit Composite-Keys, TTL und partitionsbasierter Multi-Tenancy entwerfen
- Eingabevalidierung mit einem Schema-Registry-Muster implementieren
- DynamoDB-gestuetztes Rate-Limiting mit Fail-Closed-Design hinzufuegen
- SES-Bounces und -Beschwerden mit einer SNS-getriggerten Unterdrueckungsliste behandeln
- CloudWatch-Metrikfilter und -Alarme fuer Produktions-Monitoring einrichten
- Das Backend mit einem statischen Frontend unter Verwendung von Honeypot-Spam-Schutz integrieren
- Mehrere Websites von einem einzelnen Deployment aus unterstuetzen mit einer Site-Registry
Auf dieser Seite
Dieses Tutorial fuehrt durch den Aufbau und das Deployment eines vollstaendigen serverlosen Kontaktformular-Backends mit AWS SAM. Das System behandelt die Formular-Einreichung, Eingabevalidierung, DynamoDB-gestuetztes Rate-Limiting, E-Mail-Benachrichtigungen ueber SES, Bounce-Behandlung und Monitoring — und es unterstuetzt mehrere Websites von einem einzelnen Deployment aus.
Die meisten “serverlosen Kontaktformular”-Tutorials decken eine einzelne Lambda-Funktion mit hartkodierten E-Mail-Adressen ab. Das reicht fuer einen persoenlichen Blog, aber es bricht fuer jede ernsthafte Nutzung zusammen. Dieses Tutorial baut eine produktionsreife Variante: Multi-Site-Support, anstaendige Validierung, Rate-Limiting, das Missbrauch tatsaechlich stoppt, Bounce-Behandlung, die Ihren SES-Ruf schuetzt, und Monitoring, das Ihnen sagt, wenn etwas bricht.
Der vollstaendige Quellcode ist auf GitHub unter serverless-contact-form verfuegbar.
Schritt 1: SAM-Projekt und Template einrichten
Das SAM-Template definiert die gesamte Infrastruktur: API Gateway, Lambda-Funktionen, DynamoDB-Tabellen, SES-Konfiguration und CloudWatch-Ressourcen. Das Projekt verwendet TypeScript fuer die Lambda-Funktionen und esbuild fuer schnelle Builds.
Das Template verwendet Parameter fuer die Konfiguration, damit Sie Staging- und Produktionsumgebungen aus demselben Template deployen koennen. Globale Funktionseinstellungen definieren Runtime, Timeout und Speicher fuer alle Lambda-Funktionen.
Projektstruktur
Die Projektstruktur folgt SAM-Konventionen:
template.yaml— SAM-Template mit allen Ressourcensrc/handlers/— Lambda-Funktionshandlersrc/lib/— geteilte Bibliotheken (Validierung, Rate-Limiting, E-Mail)src/config/— Site-Registry und Schema-Definitionenevents/— Test-Events fuer lokales Debugging
Lokale Entwicklung starten
sam build
sam local start-api
Schritt 2: DynamoDB-Schema entwerfen
Das Schema verwendet ein Single-Table-Design mit Composite-Keys fuer die Submissions-Tabelle und eine separate Tabelle fuer die E-Mail-Unterdrueckungsliste.
Submissions-Tabelle
Die Submissions-Tabelle verwendet siteId als Partition-Key und einen sortierten zusammengesetzten Sort-Key aus Zeitstempel und Submissions-ID. Das erlaubt effiziente Abfragen nach Site und Zeitbereich. TTL wird fuer automatische Bereinigung alter Einreichungen verwendet.
Fuer das Rate-Limiting wird ein separates Item-Muster im selben Table verwendet: Die IP-Adresse als Teil des Sort-Keys ermoeglicht das Zaehlen von Einreichungen pro IP in einem Zeitfenster.
Unterdrueckungstabelle
Die Unterdrueckungstabelle speichert E-Mail-Adressen, die Bounces oder Beschwerden erzeugt haben. Vor dem Senden einer E-Mail prueft die Sendefunktion diese Tabelle und ueberspringt Adressen, die unterdrueckt sind.
Schritt 3: Den Submit-Handler erstellen
Der Submit-Handler ist die Haupt-Lambda-Funktion, die Formular-Einreichungen verarbeitet. Er validiert die Eingabe, prueft Rate-Limits, speichert die Einreichung in DynamoDB und sendet Benachrichtigungen ueber SES.
Der Middleware-Ansatz trennt Bedenken sauber: Jeder Schritt (Validierung, Rate-Limiting, Speicherung, E-Mail) ist ein separates Modul, das unabhaengig getestet werden kann.
CORS-Konfiguration
Da das Formular-Frontend auf einer anderen Domain als die API gehostet wird, ist korrekte CORS-Konfiguration entscheidend. Die API gibt die richtigen Access-Control-Headers zurueck, einschliesslich Access-Control-Allow-Origin fuer die konfigurierten Domains.
Schritt 4: Validierung und Rate-Limiting hinzufuegen
Schema-Registry
Die Schema-Registry definiert, welche Felder jede Site akzeptiert und welche erforderlich sind. Das ermoeglicht verschiedene Formularstrukturen fuer verschiedene Websites, die vom selben Backend bedient werden.
Site-Registry
Die Site-Registry definiert, welche Websites das Formular-Backend verwenden duerfen. Jeder Site-Eintrag enthaelt:
- erlaubte Domains fuer CORS
- Empfaenger-E-Mail-Adressen
- Rate-Limit-Konfiguration
- Schema-Referenz
DynamoDB-gestuetztes Rate-Limiting
Das Rate-Limiting verwendet DynamoDB-Conditional-Writes, um Einreichungen pro IP-Adresse in einem gleitenden Zeitfenster zu zaehlen. Das Design ist fail-closed: Wenn der DynamoDB-Aufruf fehlschlaegt, wird die Einreichung abgelehnt, statt durchgelassen.
Schritt 5: SES-E-Mail-Benachrichtigungen einrichten
Zwei Arten von E-Mails werden gesendet:
- Admin-Benachrichtigung: Informiert den Site-Owner ueber eine neue Einreichung
- Benutzer-Bestaetigung: Bestaetigt dem Absender, dass seine Nachricht empfangen wurde
Beide verwenden HTML-Templates mit Pro-Site-Branding. Die Templates werden aus der Site-Konfiguration geladen, sodass jede Website ihre eigene Marke und Antwortadresse haben kann.
SES-Konfiguration
Stellen Sie sicher, dass Ihre Sender-Domain oder E-Mail-Adresse in SES verifiziert ist. Fuer Produktions-Nutzung beantragen Sie, SES aus dem Sandbox-Modus zu befreien.
Schritt 6: Bounces und Beschwerden behandeln
SES kann Benachrichtigungen senden, wenn E-Mails bouncen oder als Spam gemeldet werden. Der Stack konfiguriert SNS-Topics fuer Bounces und Beschwerden und eine Bounce-Handler-Lambda-Funktion, die:
- Die Bounce/Complaint-Benachrichtigung von SNS empfaengt
- Die betroffene E-Mail-Adresse in die Unterdrueckungstabelle eintraegt
- Einen Alarm ausloest, wenn Bounce-Raten steigen
Das schuetzt Ihren SES-Senderuf, der direkt beeinflusst, ob Ihre E-Mails zugestellt werden.
Schritt 7: Monitoring und Alarme hinzufuegen
CloudWatch-Metrikfilter extrahieren Schluesselmetriken aus den Lambda-Logs:
- Fehlerzahl pro Funktion
- Rate-Limit-Ablehnungen
- Bounce-Zaehler
- Auth-Fehler (ungueltige API-Keys oder unbekannte Sites)
CloudWatch-Alarme benachrichtigen ueber SNS, wenn Schwellenwerte ueberschritten werden.
Deployment
Deployen Sie den vollstaendigen Stack:
sam build
sam deploy --guided
Der Guided-Deploy fragt nach Parametern wie Stack-Name, Region und den konfigurierten Site-Domains.
Schritt 8: Das Frontend-Kontaktformular erstellen
Das Frontend ist ein einfaches HTML-Formular mit:
- Client-seitiger Validierung fuer erforderliche Felder
- Honeypot-Feld fuer Spam-Praevention (ein verstecktes Feld, das Bots ausfuellen, Menschen aber nicht)
- Graceful Fehlerbehandlung mit benutzerfreundlichen Nachrichten
- AJAX-Einreichung ohne Seitenneuladen
Das Honeypot-Feld ist die einfachste effektive Spam-Praevention: Wenn das versteckte Feld ausgefuellt ist, lehnt die API die Einreichung still ab. Das blockiert die meisten automatisierten Bots ohne CAPTCHA-Reibung fuer echte Benutzer.
Integration mit Ihrem Static-Site-Generator
Das Formular sendet eine POST-Anfrage an Ihren API-Gateway-Endpunkt. Fuer Astro, Next.js, Hugo oder jede andere statische Website fuegen Sie das Formular-HTML und das JavaScript ein und konfigurieren die API-URL als Umgebungsvariable.
Haeufige Einrichtungsprobleme
CORS-Fehler im Browser
Ursache: Die Domain des Frontends stimmt nicht mit der erlaubten Origin in der Site-Registry ueberein.
Loesung: Stellen Sie sicher, dass die exakte Domain (einschliesslich Protokoll) in der Site-Registry-Konfiguration aufgefuehrt ist.
SES sendet keine E-Mails
Ursache: SES befindet sich noch im Sandbox-Modus oder die Sender-Adresse ist nicht verifiziert.
Loesung: Verifizieren Sie die Sender-Domain in SES und beantragen Sie bei Bedarf die Befreiung vom Sandbox-Modus.
Rate-Limiting lehnt alle Anfragen ab
Ursache: DynamoDB-Tabelle wurde nicht korrekt erstellt oder die IAM-Berechtigungen fehlen.
Loesung: Pruefen Sie die CloudWatch-Logs des Lambda fuer Berechtigungsfehler und verifizieren Sie, dass die DynamoDB-Tabelle existiert.
Bounces steigen und SES-Ruf sinkt
Ursache: Sie senden an ungueltige Adressen ohne Unterdrueckung.
Loesung: Stellen Sie sicher, dass der Bounce-Handler korrekt deployed ist und die Unterdrueckungstabelle vor dem E-Mail-Versand geprueft wird.
Zusammenfassung
Sie haben nun ein vollstaendiges serverloses Kontaktformular-Backend, das fuer den Produktionseinsatz bereit ist: Multi-Site-Support mit einer Site-Registry, Schema-validierte Eingaben, DynamoDB-gestuetztes Rate-Limiting mit Fail-Closed-Design, SES-E-Mail-Benachrichtigungen mit Pro-Site-Branding, automatische Bounce-Behandlung zum Schutz Ihres Senderufs, CloudWatch-Monitoring mit Alarmen und ein Frontend-Formular mit Honeypot-Spam-Schutz.
Die haeufigsten naechsten Schritte sind: reCAPTCHA oder Turnstile hinzufuegen fuer staerkere Bot-Praevention, Dateianhang-Support, Webhook-Integration fuer Slack oder Teams-Benachrichtigungen und eine Admin-Oberflaeche zum Anzeigen und Verwalten von Einreichungen.
Das gesamte Projekt ist Open Source und auf GitHub verfuegbar unter serverless-contact-form.