Cómo Desplegar un Formulario de Contacto Serverless con AWS SAM, Lambda y DynamoDB
Antes de comenzar
- Una cuenta de AWS con permisos para crear stacks SAM, funciones Lambda, tablas DynamoDB, APIs de API Gateway e identidades SES
- AWS CLI y SAM CLI instalados y configurados
- Node.js 22 instalado localmente
- Un dominio o dirección de email de envío verificado en SES
- Un sitio estático donde quieras añadir un formulario de contacto (Astro, Next.js, Hugo o similar)
- Familiaridad básica con TypeScript y AWS CloudFormation
Lo que aprenderás
- Definir una API serverless completa con SAM incluyendo API Gateway, Lambda, DynamoDB y SES
- Diseñar un esquema DynamoDB de tabla única con claves compuestas, TTL y multi-tenancy basada en particiones
- Implementar validación de entrada con un patrón de registro de esquemas
- Añadir rate limiting respaldado por DynamoDB con un diseño fail-closed
- Manejar rebotes y quejas de SES con una lista de supresión activada por SNS
- Configurar filtros de métricas y alarmas de CloudWatch para monitoreo en producción
- Integrar el backend con un frontend de sitio estático usando protección honeypot contra spam
- Soportar múltiples sitios desde un solo despliegue usando un registro de sitios
En esta página
Este tutorial recorre la construcción y despliegue de un backend de formulario de contacto serverless de grado de producción usando AWS SAM. La arquitectura usa API Gateway para CORS y enrutamiento, Lambda para manejo de solicitudes, DynamoDB para almacenamiento y rate limiting, y SES para notificaciones por email. Al final, tendrás un backend que soporta múltiples sitios desde un solo despliegue, incluye rate limiting y prevención de spam, maneja rebotes de email automáticamente y cuesta casi cero para tráfico típico.
Para el caso de negocio detrás de esta arquitectura, consulta Serverless Contact Forms with AWS SAM: Why They Win on Cost, Security, and Simplicity.
Comienza creando el directorio del proyecto e instalando las dependencias:
mkdir serverless-form-api
cd serverless-form-api
npm init -y
npm pkg set type="module"
npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb @aws-sdk/client-ses
npm install -D typescript @types/aws-lambda esbuild
npx tsc --init --target ES2022 --module NodeNext --moduleResolution NodeNext --outDir dist --rootDir src --skipLibCheck
Probado con: AWS SAM CLI 1.131, Node.js 22.x, TypeScript 5.7, AWS SDK v3, API Gateway HTTP API (v2). Precios de AWS y comportamiento de servicios citados a marzo de 2026.
Paso 1: Configura el proyecto y template SAM
El template SAM define toda la infraestructura del stack en un solo archivo. Comienza con la configuración global, parámetros y configuración de API Gateway.
Crea template.yaml en la raíz del proyecto:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Serverless form submission API with multi-site support
Globals:
Function:
Runtime: nodejs22.x
Timeout: 30
MemorySize: 256
Architectures:
- arm64
Environment:
Variables:
TABLE_NAME: !Ref SubmissionsTable
SUPPRESSION_TABLE: !Ref SuppressionTable
ALLOWED_ORIGINS: !Ref AllowedOrigins
NOTIFY_EMAIL: !Ref NotifyEmail
SES_FROM_EMAIL: !Ref SesFromEmail
Parameters:
AllowedOrigins:
Type: String
Default: "http://localhost:4321,http://localhost:8080"
Description: Comma-separated list of allowed CORS origins
NotifyEmail:
Type: String
Default: "admin@example.com"
Description: Email address to receive form submission notifications
SesFromEmail:
Type: String
Default: "noreply@example.com"
Description: Verified SES sender email address
La sección Globals establece defaults para todas las funciones Lambda: runtime Node.js 22, arquitectura ARM64 para mejor relación precio-rendimiento y variables de entorno compartidas. La sección Parameters hace explícita la configuración en tiempo de despliegue.
El tutorial completo continúa con diseño de esquema DynamoDB, handler de envío, validación y rate limiting, notificaciones SES, manejo de rebotes, monitoreo con CloudWatch, formulario frontend y despliegue de extremo a extremo.
Problemas Comunes de Configuración
Errores CORS en la consola del navegador
La causa más común es un desajuste entre el origen desde el que tu sitio envía solicitudes y el parámetro AllowedOrigins. Verifica que el origen incluya el protocolo y puerto (por ejemplo, http://localhost:4321, no localhost:4321). Redesplega con los orígenes corregidos.
SES sandbox bloquea emails a direcciones no verificadas
En modo sandbox, SES solo envía a direcciones de email verificadas. Verifica la dirección del destinatario en la consola de SES, o solicita acceso de envío en producción cuando estés listo para ir en vivo.
La verificación de rate limit rechaza todo
Si la consulta de conteo de DynamoDB está fallando (permisos, desajuste de nombre de tabla), el diseño fail-closed rechaza todos los envíos. Verifica los logs de CloudWatch para errores en la función de envío y verifica que la variable de entorno TABLE_NAME coincida con la tabla real.
Timeout de Lambda en envío de notificación
Si el envío de SES tarda más de lo esperado, la Lambda puede hacer timeout. El timeout por defecto es 30 segundos, que es generoso para un handler de formulario de contacto. Si ves timeouts, verifica la salud del servicio SES y que la dirección del remitente siga verificada.
El bounce handler no recibe eventos
Los topics SNS necesitan estar conectados a tu conjunto de configuración SES. En la consola de SES, crea o edita un conjunto de configuración y añade los ARNs de los topics SNS de rebotes y quejas de las salidas de SAM. Este paso no está automatizado por el template.
Conclusión
Ahora tienes un backend de formulario de contacto serverless de grado de producción: API Gateway para enrutamiento y CORS, Lambda para manejo de solicitudes, DynamoDB para almacenamiento con claves compuestas y TTL, SES para notificaciones con supresión automática de rebotes, y CloudWatch para monitoreo con filtros de métricas y alarmas.
El stack completo está definido en un solo template SAM, se despliega en dos comandos, cuesta casi cero para tráfico típico y escala a cualquier carga que llegue sin cambios de configuración.
Para extender esta arquitectura, los siguientes pasos normalmente son añadir más tipos de envío (registro de newsletter, formularios de feedback), añadir templates de email para confirmaciones de usuario y conectar las alarmas de monitoreo a un canal de notificación de equipo como Slack o PagerDuty.
Para la perspectiva de negocio sobre por qué esta arquitectura gana en costo, seguridad y simplicidad, consulta Serverless Contact Forms with AWS SAM. Para guías de seguridad relacionadas, consulta nuestra guía de mejores prácticas de seguridad de APIs y el Serverless Form Architecture Checklist.