Ir al contenido
Volver a Tutoriales

Cómo Desplegar un Formulario de Contacto Serverless con AWS SAM, Lambda y DynamoDB

Intermedio · 1 hour 30 minutes · 4 min de lectura · Byte Smith ·

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
1
2
3
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
Nota

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.