Cómo usé AWS para desplegar mi sitio web de manera eficiente y escalable
AWSInfrastructureServerless
Llevo varios meses queriendo actualizar mi sitio web personal para reflejar mejor mis habilidades y proyectos recientes. Antes de cambiarlo por completo, intenté simplemente actualizar la primera versión que había creado hace tiempo, pero me di cuenta de que ya no me gustaba lo suficiente como para seguir usándolo. Así que decidí empezar desde cero con un nuevo diseño, tecnologías y arquitectura más robusta (aunque para un sitio web personal no era necesario algo más allá de una plantilla estática y el despliegue en Netlify o Vercel).
Aprovechando que acabo de certificarme en AWS como Solutions Architect - Associate, decidí implementar una arquitectura serverless en AWS. En este artículo, compartiré cómo diseñé y desplegué la arquitectura utilizando varios servicios de AWS, y las razones detrás de mis elecciones.
Diagrama de arquitectura de la solución con servicios Serverless de AWS
Sobre la Arquitectura y los Servicios
La arquitectura que implementé para mi sitio web es completamente serverless, lo que significa que no gestiono ningún servidor directamente. En su lugar, utilizo varios servicios de AWS que se encargan de la infraestructura subyacente.
A continuación, describo los principales servicios que utilizo y su función en la arquitectura con el fragmento de código correspondiente en YAML para CloudFormation:
1. Amazon S3 (Simple Storage Service)
S3 es un servicio de almacenamiento de objetos que utilizo para alojar los archivos estáticos de la carpeta out generada por Next.js (HTML, CSS, JS, imágenes, etc.). En este caso, S3 actúa como el origen para Cloudfront.
El bucket de S3 está configurado para bloquear todo el acceso público, forzar la propiedad de los objectos al propietario del bucket y versionar los archivos. Aunque estas dos últimas configuraciones no son estrictamente necesarias para un sitio web estático, las considero buenas prácticas para mejorar la seguridad y la gestión de los archivos. Sin embargo, es importante analizar si tener el versionado activo es adecuado para tu caso, ya que puede incrementar los costos de almacenamiento si no se gestiona adecuadamente con políticas de ciclo de vida.
SiteBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !If
- UseCustomBucketName
- !Ref BucketName
- !Ref DomainName
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerEnforced
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: DeleteOldVersionsRule
Status: Enabled
NoncurrentVersionExpiration:
NoncurrentDays: 30
2. Amazon CloudFront
CloudFront es una red de distribución de contenido (CDN) que utilizo para distribuir mi sitio web globalmente. CloudFront almacena en caché los archivos estáticos en ubicaciones cercanas a los usuarios, lo que reduce la latencia y mejora la velocidad de carga del sitio web. La configuración de CloudFront incluye:
OAC (Origin Access Control): Para permitir que solo CloudFront pueda acceder al bucket de S3, mejorando la seguridad.
Funciones de CloudFront: Con código personalizado para manejar redirecciones y el enrutamiento de la web, ya que Next.js genera rutas dinámicas que necesitan ser manejadas correctamente.
Certificados SSL/TLS: Gestionados a través de AWS Certificate Manager para asegurar que mi sitio web utiliza HTTPS.
Aliases: Para manejar tanto el dominio raíz como el subdominio www.
Política de caché: Utilizo una política de caché gestionada por AWS para optimizar el rendimiento.
Respuestas de error personalizadas: Para redirigir a una página 404 personalizada en caso de errores. Next.js genera la página 404.html en el build, por lo que necesito configurar CloudFront para usarla.
Clase de precio: Configurada en PriceClass_100 para limitar la distribución a las regiones más cercanas y económicas, lo que es suficiente para mi caso.
Route 53 es un servicio de sistema de nombres de dominio (DNS) de alta disponibilidad y escalable que traduce nombre de dominio como pool-llerena.com a direcciones IP.
Route 53 gestiona el dominio personalizado y apunta a la distribución de CloudFront.
La zona hospedada se crea automáticamente si el dominio es gestionado por Route 53. Sin embargo, he comprado el dominio a través de Namecheap, por lo que tuve que crear la zona hospedada con CloudFormation y luego actualizar los nameservers en Namecheap para que apunten a los de Route 53.
HostedZone:
Type: AWS::Route53::HostedZone
Properties:
Name: !Ref DomainName
HostedZoneConfig:
Comment: !Sub "Hosted zone for ${DomainName}"
# Registro A en Route 53 apuntando a CloudFront
ApexAlias:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZone
Name: !Ref DomainName
Type: A
AliasTarget:
DNSName: !GetAtt Distribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2
# Registro A para www.<domain> apuntando a CloudFront
WWWAlias:
Condition: UseWWW
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZone
Name: !Sub "www.${DomainName}"
Type: A
AliasTarget:
DNSName: !GetAtt Distribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2
4. AWS Certificate Manager (ACM)
ACM es un servicio que facilita la provisión, gestión y despliegue de certificados SSL/TLS para asegurar las conexiones a mi sitio web. Solicité un certificado para mi dominio personalizado y lo asocié con la distribución de CloudFront y la zona hospedada en Route 53 para habilitar HTTPS.
Route 53 gestiona automáticamente la validación del dominio mediante DNS, creando los registros CNAME necesarios en la zona hospedada.
Commnet: "ACM will auto-create DNS validation CNAMEs in the hosted Zone"
5. CloudFront Functions
Utilizo funciones de CloudFront para manejar redirecciones y el enrutamiento de la web. Next.js genera rutas dinámicas que necesitan ser manejadas correctamente para que los usuarios puedan acceder a las páginas sin problemas.
El código de la función es una función básica que solo devuelve la solicitud sin modificaciones porque el código real lo gestiono post-despliegue con un workflow de GitHub Actions. Esto me permite mantener la plantilla de CloudFormation más limpia y separar el código de la función del resto de la infraestructura.
WWWRedirectFunction:
Type: AWS::CloudFront::Function
Properties:
Name: !Ref RedirectFunctionName
AutoPublish: true
FunctionConfig:
Comment: !Sub "Manage application routing and redirect www.${DomainName} and CloudFront Domain Name to apex for ${DomainName}"
Runtime: cloudfront-js-2.0
FunctionCode: |
function handler(event) {
return event.request;
}
6. AWS CloudFormation
Utilizo CloudFormation para definir y desplegar toda la infraestructura como código. Esto me permite versionar la infraestructura junto con el código de mi sitio web y automatizar el proceso de despliegue.
Para ver el archivo completo de CloudFormation, puedes revisar el repositorio en GitHub
Trade-offs y Consideraciones
Elegir una arquitectura serverless en AWS para un sitio web personal tiene varias ventajas, pero también algunos trade-offs que debemos considerar:
Costo: Aunque los servicios serverless suelen ser económicos, es importante monitorear los costos, especialmente si el tráfico al sitio web aumenta significativamente. Servicios como S3 y CloudFront tienen costos basados en el uso, por lo que es crucial entender el modelo de precios.
Complejidad: Implementar y gestionar una arquitectura serverless puede ser más complejo que utilizar plataformas como Netlify o Vercel, especialmente para alguien que no está familiarizado con AWS. Sin embargo, la experiencia adquirida al trabajar con estos servicios es valiosa.
Mantenimiento: Aunque los servicios serverless reducen la carga de mantenimiento, es necesario gestionar la infraestructura como código y asegurarse de que todo esté correctamente configurado y actualizado.
Latencia: Utilizar una CDN como CloudFront ayuda a reducir la latencia, pero es importante configurar correctamente las políticas de caché y las funciones para asegurar que los usuarios siempre reciban la versión más reciente del sitio web.
Seguridad: Configurar correctamente los permisos y el acceso a los servicios es crucial para mantener la seguridad del sitio web. Utilizar OAC para CloudFront y bloquear el acceso público al bucket de S3 son buenas prácticas que he implementado.
Costos Estimados
El costo mensual estimado para alojar mi sitio web utilizando esta arquitectura serverless en AWS es relativamente bajo, especialmente considerando que el tráfico a mi sitio web no es alto.
Nivel de Tráfico
Amazon S3
CloudFront
Route 53
ACM
Total Mensual
Bajo (1K visitas/mes)
$0.02
$0.15
$0.50
Gratis
$0.67
Moderado (10K visitas/mes)
$0.05
$1.46
$0.51
Gratis
$2.02
Alto (100K visitas/mes)
$0.26
$14.63
$0.53
Gratis
$15.42
Con Free Tier (cualquier nivel)
$0.00
$0.00
$0.53
Gratis
$0.53
Nota sobre CloudFront: Los costos están calculados basándose en los datos reales del sitio:
25 requests por visita (HTML, CSS, JS, imágenes, fuentes, etc.)
1.5MB transferidos por visita (archivos comprimidos)
El Free Tier de CloudFront (1TB + 10M requests/mes) cubre completamente el tráfico bajo y moderado
Desglose Detallado de Costos
Amazon S3:
Almacenamiento: $0.023 por GB al mes.
Solicitudes PUT/COPY/POST/LIST: $0.005 por 1,000 solicitudes
Solicitudes GET: $0.0004 por 1,000 solicitudes
Nota: Con CloudFront y caché optimizada, las solicitudes directas a S3 son mínimas
Amazon CloudFront:
Transferencia de datos: $0.085 por GB (primeros 10 TB/mes)
Solicitudes HTTP/HTTPS: $0.0075 por 10,000 solicitudes
CloudFront Functions: $0.10 por millón de ejecuciones
Nota: El tráfico se sirve principalmente desde caché, reduciendo transferencias desde S3
Amazon Route 53:
Zona hospedada: $0.50/mes (zona básica)
Consultas DNS estándar: $0.40 por millón de consultas
Nota: Las consultas de alias hacia CloudFront son gratuitas
AWS Certificate Manager (ACM):
Certificados SSL/TLS públicos: Gratis para uso con CloudFront
Costo real con Free Tier activo: Solo la zona hospedada de Route 53 ($0.50/mes) + consultas DNS adicionales ($0.40/millón de consultas estándar). Para un sitio web personal, esto resulta en aproximadamente $0.51/mes.
Conclusión
Implementar mi sitio web personal utilizando una arquitectura serverless en AWS ha sido una experiencia enriquecedora que me ha permitido aprender y aplicar varios servicios de AWS. La combinación de S3, CloudFront, Route 53, ACM y CloudFormation me ha proporcionado una solución robusta, escalable y segura para alojar mi sitio web.
Si estás considerando desplegar un sitio web personal o cualquier otra aplicación estática, te animo a explorar las opciones que AWS ofrece y a experimentar con una arquitectura serverless. Aunque puede haber una curva de aprendizaje, los beneficios en términos de escalabilidad, costo y mantenimiento pueden ser significativos.