Servir un sitio estático a través de HTTPS utilizando S3, Route 53, Certificate Manager y CloudFront

En este tutorial se utilizarán las siguientes tecnologías:

  • AWS S3: Almacenamiento en la nube en el que alojaremos nuestro sitio estático.

  • AWS Route 53: DNS que resolverá el dominio personalizado que utilizaremos en nuestro sitio.

  • AWS Certificate Manager: Servicio con el que obtendremos el certificado SSL/TLS público que será utilizado para servir el sitio a través de HTTPS.

  • AWS CloudFront: Servicio CDN con el que serviremos nuestro contenido, es decir, nuestra página no será servida directamente de S3.

Para desarrollar este tutorial es necesario que ya hayan completado los siguientes tutoriales:

O bien, que tengas un sitio estático publicado en S3 y un dominio registrado en Route 53.

1. Obtener el certificado SSL/TLS público que será utilizado para servir el sitio a través de HTTPS.

Buscamos el servicio AWS Certificate Manager en nuestra consola.

Una vez dentro seleccionamos Get Started para obtener nuestro primer certificado.

Pedimos un certificado publico para nuestro sitio, estos son gratuitos en AWS.

Ingresamos los records para nuestro dominio.

Seleccionamos DNS validation.

Confirmamos nuestros datos y hacemos la solicitud.

Luego nos aparecen pendientes de validación ambos records.

Procedemos a crear los records que nos solicitan en Route 53 para validar que somos dueños del dominio en cuestión.

Creamos el record.

Luego de crearlo tenemos que esperar algun tiempo para que la validación se haga efectiva.

Al finalizar tendremos ambos records validados y nuestro certificado podrá ser utilizado.

2. Configurar nuestro CDN en AWS CloudFront

En la consola de AWS buscamos el servicio Cloudfront. Una vez dentro seleccionamos Create Distribution para crear nuestro primer CDN.

Seleccionamos Get Started en el segmento de Web distribution, pues es una distribución de este tipo la que queremos crear.

Ingresamos el nombre en Origin Domain Name y automáticamente se asignará un Origin ID, podemos dejar ese que se asigne, este es un nombre que nos permitira identificar el origen dentro de la distribución.

Seleccionamos la opción Restrict Bucket Access: Yes, esto hará que nuestro bucket que inicialmente era público deje de serlo para que podamos acceder a los archivos del bucket solamente a través de nuestro CDN, de nuestra distribución de CloudFront.

Seleccionamos Origin Access Identity: Create a New Identity, esto creará un identificador que se usará para crear una política en S3 que permita a nuestro CDN acceder a los recursos de S3, que ya no serán públicos debido a la configuración anterior.

Seleccionamos Grant Read Permissions on Bucket: Yes, Update Bucket Policy, esta opción actualizará la política de nuestro bucket y la cambiará para que deje de ser público y comience a ser solamente accesible para nuestro CDN.

En la configuración Viewer Protocol Policy, seleccionamos la opción Redirect HTTP to HTTPS, pues este el principal objetivo en este tutorial, servir la página con a través de HTTPS.

En la configuración Compress Objects Automatically seleccionamos la opción Yes.

En la sección Distribution Settings, hacemos lo siguiente:

Configuramos nuestros nombres de dominio en la opción Alternate Domain Names (En este caso agregaré ericknavarro.io, y adicionalmente www.ericknavarro.io, para que también funcione con esta dirección).

Configuramos el certificado SSL generado anteriormente seleccionando Custom SSL Certificate (example.com), al entrar en la caja de texto nos lo desplegará automáticamente y podremos seleccionarlo:

Configuramos en Default Root Object, nuestra página principal, en este caso index.html.

El resto de configuraciones las dejamos con sus valores por defecto y procedemos a hacer click en Create Distribution.

Al finalizar la creación, el status será Deployed y el state será Enabled. Al visitar el nombre de dominio, que en este caso es:

1
d22ckq6fuymrpu.cloudfront.net

Veremos nuestra página, que está siendo servida a través de HTTPS:

3. Apuntar nuestro dominio hacia el CDN creado

Lo primero es buscar el servicio Route 53 en la consola de AWS.

Posteriormente vamos a hosted zones, encontraremos una hosted zone para nuestro dominio, ingresamos a él haciendo click en su identificador.

Una vez dentro encontraremos la configuración actual, en mi caso tenía un record set que apuntaba directamente a S3, eliminé ese record set y procedí a crear uno nuevo, para ello hacemos click en Create Record Set.

Dentro del wizard, configuramos un Record Set de tipo A, que sea un alias cuyo target sea nuestro CDN de CloudFront, si entramos en este campo, nuestro CDN debería aparecer en el listado.

Hacemos click en Create y listo, tenemos creado el primer record set.

Es necesario que creemos 3 record sets más, hasta completar los siguientes 4 recordsets, los A para IPv4 y los AAAA para IPv6, en mi caso estos record sets quedarán de la siguiente manera:

1
2
3
4
5
Record   Domain                Alias Target
A | ericknavarro.io | d22ckq6fuymrpu.cloudfront.net
AAAA | ericknavarro.io | d22ckq6fuymrpu.cloudfront.net
A | www.ericknavarro.io | d22ckq6fuymrpu.cloudfront.net
AAAA | www.ericknavarro.io | d22ckq6fuymrpu.cloudfront.net

Al finalizar tendremos algo como lo siguiente:

Si consultamos nuevamente nuestro dominio ericknavarro.io, podremos observar que la página ya está siendo servida a través de HTTPS:

En este momento hemos alcanzado nuestro objetivo, que era servir un sitio estático a través de HTTPS utilizando S3, Route 53, Certificate Manager y CloudFront.

Algunas anotaciones sobre lo configurado:

  • Si por algún motivo necesitaramos cambiar el contenido de la página, además de actualizar los archivos en S3, deberíamos hacer un invalidate en nuestra distribución, pues la distribución guarda en cache la información de la página y lo que nos muestra es siempre información que tiene cacheada, esta información se cachea la primera vez que accedemos a la página. Hacer un invalidate, se puede traducir a borrar la cache.

  • Si vamos a nuestro bucket veremos que la política ha cambiado y el único recurso con permisos para acceder al bucket es nuestra distribución, lo que significa que el bucket ya no es público y no podemos acceder a él directamente desde el navegador, tenemos que hacerlo a través de nuestra distribución.

Con esto hemos llegado al final de nuestro tutorial.

Agregar un dominio personalizado a tu sitio utilizando Amazon Route 53

En este tutorial se asume que tienes un sitio estático publicado en S3, al que deseas apuntar un dominio personalizado. Si quieres saber más sobre este tema, puedes revisar mi post: Publicar un sitio estático en Amazon S3.

Para agregar un dominio personalizado a nuestro sitio, utilizaremos el servicio Amazon Route 53.

Lo primero es buscar el servicio Route 53 en la consola de AWS.

Una vez dentro de la consola Route 53, escribimos el nombre de dominio que deseamos comprar, presionamos check y verificamos su existencia.

Si no estuviera disponible, AWS nos recomendará otros dominios similares disponibles.

Luego de comprarlo vamos a Registered domains, en donde encontraremos el dominio comprado.

Posteriormente vamos a hosted zones, encontraremos una hosted zone para nuestro dominio, ingresamos al hosted zone de nuestro dominio.

Una vez dentro encontraremos la configuración actual de nuestro dominio, para hacer que nuestro dominio apunte hacia el bucket de S3 que contiene nuestro sitio debemos crear un nuevo Record Set.

Dentro del wizard, configuramos un Record Set de tipo A, que sea un alias cuyo target sea nuestro bucket de S3 que almacena el sitio estático, si entramos en este campo, nuestro bucket debería aparecer en el listado.

 

 

Una vez creado el record set, ya podemos cargar nuestra página estática mediante el nombre de dominio que compramos.

Vemos que la página de error funciona correctamente siempre sobre el dominio configurado.

Con esto nuestro sitio estático está listo con un dominio personalizado.

Publicar un sitio estático en Amazon S3

Amazon Simple Storage Service (Amazon S3) es un servicio de almacenamiento de objetos que ofrece escalabilidad, disponibilidad de datos, seguridad y rendimiento líderes en el sector.

Un beneficio importante de S3 es la posibilidad de publicar sitios estáticos, sitios para los que no tenemos que configurar un servidor web, sitios serverless.

Lo primero es buscar el servicio S3 en la consola de AWS. Los sitios estáticos que son publicados en S3 deben tener su propio bucket, por lo que crearemos uno para nuestro sitio, hacemos click en create bucket.

En el asistente de creación del bucket:

  • Name and Region: Indicamos el nombre del bucket, en mi caso es ericknavarro.io, este nombre debe ser único en todo el universo de buckets de AWS, puede que el nombre del bucket ya exista, si es ese el caso recibiremos un mensaje de error y tendremos que modificar el nombre del bucket, dejamos los valores por defecto para el resto de opciones.

  • Configure options: Dejamos los valores por defecto para estas opciones.

  • Set permissions: Nos aseguramos que las restricciones para asignar permisos publicos no estén chequeadas, estas opciones aparecen en la siguiente imagen encerradas en dos recuadros amarillos, podemos dejar las opciones de configuración por defecto.

  • Review: Validamos que toda la configuración realizada corresponda con lo que necesitamos y creamos el bucket.

Una vez creado el bucket veremos una imagen como la siguiente en nuestra consola, hacemos click en el bucket e incresamos a las opciones.

Una vez dentro nos movemos a la pestaña de Properties y hacemos click en la sección Static website hosting.

Una vez dentro se nos indica el Endpoint que es la URL con la que llegamos al sitio publicado, además tenemos que indicar el nombre de nuestro documento index y de nuestro documento error, en nuestro caso se llamarán index.html y error.html, pero podrían ser otros documentos con nombres diferentes.

1
2
Endpoint:
[http://ericknavarro.io.s3-website-us-east-1.amazonaws.com/](http://ericknavarro.io.s3-website-us-east-1.amazonaws.com/)

Posteriormente nos movemos a la pestaña de permisos y configuraremos una política en la pestaña Bucket Policy para que todos los archivos que se carguen al bucket sean públicos, esta política será:

1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::**ericknavarro.io**/*"
}
]
}

Es importante cambiar el nombre del bucket dentro de la política, en este caso el nombre de mi bucket es ericknavarro.io, pero este debe reemplazarse con el nombre del bucket que se usará para publicar el sitio.

Ahora procedemos a cargar los archivos HTML de nuestra página estática, en primero es index.html, que es nuestra página principal:

1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Erick Navarro</title>
</head>
<body>
<h1>Esta es una página estática publicada en S3.</h1>
</body>
</html>

El segundo es error.html, que es una página secundaria a la que se redirigirá ante cualquier error, por ejemplo, que el usuario intente ingresar a una página inexistente dentro del bucket:

1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Erick Navarro</title>
</head>
<body>
<h1>Hemos tenido un error.</h1>
</body>
</html>

En nuestro bucket tenemos la opción de cargar archivos (Upload) en la vista Overview:

Seleccionamos los archivos

Tendremos nuestro sitio cargado

Visitamos el endpoint de nuestra página:

1
2
Endpoint:
[http://ericknavarro.io.s3-website-us-east-1.amazonaws.com/](http://ericknavarro.io.s3-website-us-east-1.amazonaws.com/)

Podremos observar el contenido de la página index.html.

Luego de intentar ingresar a una página que no existe en nuestro sitio, S3 nos redirige a la página de error que publicamos:

Con lo anterior tenemos nuestro sitio estático publicado en S3.

Si quieres asignar un dominio personalizado a tu sitio, revisa mi post: Agregar un dominio personalizado a tu sitio utilizando Amazon Route 53

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×