Hospedar un Sitio Web Estático con Amazon S3 y CloudFront

Gabriel Ramírez
AWS User Group México
6 min readSep 12, 2018

El Servicio Simple de Almacenamiento ó S3 es una excelente opción para hospedar un sitio web estático ya que nos da los siguientes beneficios:

  • Almacenar nuestros archivos con una durabilidad de 99,999999999% lo cual lo hace un medio extremadamente robusto para evitar pérdida ó corrupción de nuestra información.
  • Alta disponibilidad SLA 99.99%
  • Bajo Costo $0.023 USD — $0.44MXN por GB y $0.005 USD por cada 1000 solicitudes PUT, COPY, POST o LIST (más costos de transferencia de datos)
  1. El primer paso es crear un bucket en donde estaremos hospedando nuestro sitio web, para el caso en el que se vaya a configurar un nombre de dominio apuntando como origen a nuestro bucket el nombre del bucket debe de ser el mismo

En este caso he registrado el nombre de dominio s3websitehosting con Route53

  • Para la creación del bucket es importante tomar en cuenta la latencia, esto es el tiempo de respuesta desde la región geográfica en la que estamos creando nuestros recursos; CloudPing.info es un buen lugar para consultar esta información
  • Las primeras opciones nos dan buenos tiempos de respuesta, otros criterios adicionales a tomar en cuenta pueden ser servicios adicionales como EC2, VPC que esten ejecutando en ciertas regiones, disponibilidad de features ó diferencias en costos.

2. Una vez creado el bucket vamos a crear nuestra webApp de forma local. Una buena opción es utilizar un generador para hacer un bootstrapping de nuestra aplicación web, en lo personal me gusta yeoman.io

vamos a instalar las dependencias que nos pide el proyecto (se requiere de un ambiente de NodeJS reciente y NPM). Para este proyecto utilizaré AngularJS generator

npm install -g grunt-cli bower yo generator-karma generator-angular

Ahora creamos el directorio del proyecto

mkdir webApp && cd $_

Y por último especificar el nombre del proyecto

yo angular static_website

Deben de recibir una salida como la siguiente, si no es el caso arreglen los problemas que por lo general son asociados a dependencias o versiones no actuales de repositorios y vuelvan a intentarlo. Pueden optar por otros generadores como por ejemplo JQuery

Done, without errors.

Ejecutemos grunt serve para visualizar la aplicación web de forma local y grunt para preparar la aplicación para producción.

Una gran ventaja de utilizar este tipo de workflows es que grunt se encarga de realizar múltiples tareas con nuestro código como por ejemplo minificación y compresión de archivos fuente e imagenes. Cuando utilicemos CloudFront para acelerar nuestro sitio utilizando ubicaciones borde de cache es importante tener una estrategia que nos permita invalidar las versiones antiguas de nuestra aplicación. Para esto existen diferentes estrategias pero una muy eficiente es versionar nuestros archivos, así CloudFront puede identificar cuando se ha producido un cambio en los archivos origen y cachear la ultima versión disponible.

3. Ahora vamos a proceder a subir nuestro sitio web al bucket creado de S3 (vamos a utilizar el directorio webApp/dist para subir esta versión productiva)

aws s3 sync . s3://s3websitehosting --acl public-read
  • Si utilizan múltiples cuentas de aws deberán especificar un perfil y deben tener instalado y configurado el CLI de AWS
  • El comando anterior encontrará las diferencias entre la ubicación origen y destino para después sincronizarlos, en este caso mi directorio actual de trabajo y el bucket destino.

4. Actualicemos la configuración del bucket para hostear un sitio web estático

aws s3 website s3://s3websitehosting.com — index-document index.html — error-document 404.html
  • Comprobemos que los cambios han surtido efecto (esto también puede hacerse desde la consola)
  • Existe un cliente de línea de comandos de más bajo nivel que se llama s3-api y es mucho mas robusto para acceder de forma mas directa a la API de S3 en donde pueden especificar reglas de redireccionamiento como por ejemplo http a https.

El sitio web que he creado ahora es accesible a través de la siguiente URL

https://s3-us-west-1.amazonaws.com/s3websitehosting.com/index.html#!/

Ahora que hemos subido nuestros archivos es una buena idea hacer una prueba de performance, en mi caso entrega los siguientes valores de latencia (743ms).

743ms

5. Para establecer reglas de ruteo en nuestro sitio web y poder redireccionar peticiones de http://www.s3websitehosting.com a http://s3websitehosting.com necesitaremos dos buckets. Sólo en uno de ellos se encontrará hospedado nuestro sitio web y el otro actuará como un alias del origen.

En este caso el bucket www apunta al origen dominio.com

6. Procedamos a crear registros alias para asociar nuestro nombre de dominio al sitio web estático en el bucket de s3, en Route53 debemos de editar el archivo de zona público para crear un registro de tipo ALIAS.

La propagación de nombres de DNS es bastante rápida en cuestión de segundos ya debe de resolver el nombre, si pruebo en mi navegador

Pero si busco www.s3websitehosting.com me devuelve un error

Esto se soluciona fácilmente estableciendo otro ALIAS pero en esta ocasión agregando el prefijo www (repetir el proceso anterior pero indicando en Name www)

Si filtramos los registros de tipo ALIAS deben de tener algo muy similar a esto pero con su propio nombre de dominio.

Esto generará un redireccionamiento automático de www al APEX

Ahora es tiempo de acelerar nuestro sitio web poniendo al frente una distribución web de cloudfront para que la página web se copie el múltiples ubicaciones borde y mejorar la experiencia del usuario

7. Lo primero es crear una distribución web en CloudFront con los siguientes valores

  • Esperar hasta que el estatus de la distribución haya cambiado a “Deployed”

Copiar el Domain Name generado y probarlo en un navegador debe de ser algo como XXXXXXXXXXXX.cloudfront.net

¡Y listo! ahora tienes tu sitio cacheado en +50 servidores borde de AWS y siempre que se utilice este nombre de dominio el servicio determinará automáticamente el mejor candidato para servir el contenido

Aqui les muestro el benchmark entre el bucket s3 y el sitio acelerado por CloudFront

1.03s vs 36ms = +70% performance

8. Por último actualizar los registros de Route53 para asociar el nuevo alias, esta ocasión al CNAME de la distribución web de CloudFront y no el bucket origen en s3

  • Repetir este proceso para el nombre origen

Validamos que los registros Alias ahora tienen el valor del CNAME de CloudFront

Haciendo nuevamente una prueba podemos ver que el sitio es servido por la caché y no por el origen

X-Cache: Hit from cloudfront

¡Felicidades¡ Acabas de desplegar una solución en alta disponibilidad con muy bajo costo y con un excelente desempeño para aplicaciones web :)

--

--

Gabriel Ramírez
AWS User Group México

AWS Community HERO | Founder of Bootcamp Institute | Author of AWS Certified Solutions Architect — Associate Guide