Navigate back to the homepage

Desplegar Gatsby en CloudFront y Lambda Edge

Javier Fonseca
January 28th, 2020 · 2 min read

En el artículo anterior donde se explicaba como desplegar Gatsby usando AWS Amplify encontré que CloudFront no funcionama como se esperaba que era mostrar el sitio qlojado en el caché y cada vez que se mostraba la página las imagenes tomaban tiempo para cargar, además que cada vez que se abría en una pestaña nueva cualquier link, se redirigía a la vista inicial.

Estos problemas se debían a que Amplify esperaba que se mostrara el archivo index.html de cada ruta generada en el build, al no estar debidamente configurada no podía encontrar dicho archivo y tampoco podía encontrar ni mostrar la vista el error 404.

La solución encontrada fue la siguiente:

Configurar Gatsby

Asegurar que toda url generada por Gatsby culminara en slash ’/‘.

Para esto se debe instalar un plugin

1yarn add gatsby-plugin-canonical-urls

Luego agregar en la sección de plugins los siguiente

1{
2 resolve: `gatsby-plugin-canonical-urls`,
3 options: {
4 siteUrl: `https://javierfonseca.me`,
5 },
6 },

Configurar AWS Amplify

Se debe crear una nueva instancia de Amplify

1amplify configure

Luego agregar el hosting, seleccionar S3 con CloudFront

1amplify add hosting

Este proceso de configuración crea un nuevo S3 Buckect y lo relaciona con una nueva distribución de CloudFront.

Para hacer la publicación a AWS se debe usar el siguiente comando

1amplify publish

Configurar Route 53

En caso que el dominio esté registrado en AWS, se debe actualizar el DNS a la nueva distribución de CloudFront para que los cambios se puedan visualizar.

Configurar CloudFront

Asegurar que todo error en url mostrara error 404

En la distribución creada de CloudFront, seleccionar la pestaña Error pages, modificar 404 en Response Page Path por `/404/“

CloudFront-Error

Lambda Edge

Edge es un nuevo servicio de AWS para CloudFront que según como se describe sirve para mejorar el performance y reducir la latencia, cualquier función puede ser usada para el antes, durante y después de que CloudFront reciba un request. Para la solución se usará para el evento antes de procesar el request.

Crear función Lambda

Para preprocesar el request recibido por CloudFront la función debe ser creada usando la versión de NodeJS 10.16.3 y el cuerpo de la función debe ser la siguiente

1'use strict';
2var path = require('path');
3exports.handler = (event, context, callback) => {
4
5 function is_numeric(str){
6 return /^\d+$/.test(str);
7 }
8
9 // Extrae el request de CloudFront que va a ser enviado a Lambda@Edge
10 var request = event.Records[0].cf.request;
11
12 // Extrae la URI del request
13 var olduri = request.uri;
14
15 // Extrae la extensión de la URI
16 var extension = path.extname(olduri);
17
18 // Extrae el último caracter de la URI
19 var last_character = olduri.slice(-1);
20
21 // Valida si el última caracter es un número, esto sirve para evitar redirección al navegar en el paginador.
22 if (is_numeric(last_character) === true) {
23 return callback(null, request);
24 }
25 else {
26 // Asigna /index.html para que CloudFront pueda encontrar la ubicación de la URL
27 var newuri = `${olduri}/`;
28 newuri = olduri.replace(olduri.slice(-1), '\/index.html');
29 request.uri = newuri;
30 return callback(null, request);
31 }
32};

Este código reconstruye la url para que CloudFront reconozca la ubicación del archivo html, en el browser no se verá cambio alguno porque no hace la reescritura como lo haría un servidor Apache o NGINX.

La validación de la estensión y último caracter es para poder mostrar los demas archivos como los assets y js, en este caso lambda no hace ningun cambio y devuelve la urice tal como se solicitó.

Modificación del rol creado por Lambda para reconocer CloudFront

Cuando se creó Lambda si se seleccionó “crear nuevo rol” o “usar rol existente” se debe agregar un Trust Relationship de edgelambda para que se pueda generar la réplica de CloudFront

Al hacer click en Edit trust relationship el json debe quedar de la siguiente forma

1{
2 "Version": "2012-10-17",
3 "Statement": [
4 {
5 "Effect": "Allow",
6 "Principal": {
7 "Service": [
8 "edgelambda.amazonaws.com",
9 "lambda.amazonaws.com"
10 ]
11 },
12 "Action": "sts:AssumeRole"
13 }
14 ]
15}

Invalidar caché de CloudFront

En caso que se haya ingresado a cualquier url del sitio y se necesite ver los cambios generados, se debe limpiar el caché de CloudFront porque por default el caché dura 24 horas, para crear la invalidación se debe modificar directamente en la distribución usando /*

CloudFront Invalidation

Agregar réplica de CloudFront a Lambda

En la consola de Lambda se debe hacer lo siguiente

Seleccionar Deploy to Lambda@Edge

Seleccionar Deploy to Lambda@Edge

Crear réplica

Seleccionar Add Trigger y luego CloudFront

Configurar Deploy to Lambda@Edge

Como paso final, queda esperar a que se progague en todo Cloudfront para poder acceder al sitio, de lo contrario se verá Access denied al llamar a la url.

Una vez finalizada la propagación las imagenes se cargarán más rápido y todos los links estarán funcionales

Share

More articles from Javier Fonseca's Blog

Cómo agregar ads de #BTC en tu blog

Pasos para usar Anonimous Ads y comenzar a ganar Bitcoins con publicidad

January 26th, 2020 · 1 min read

Desplegar Gatsby en AWS Amplify

Pasos para desplegar Gatsby en AWS Amplify en pocos minutos

January 21st, 2020 · 1 min read
© 2020 Javier Fonseca's Blog
Link to $https://twitter.com/fonsecaj89Link to $https://www.facebook.com/FonsecaJ89Link to $https://github.com/Fonsecaj89Link to $https://www.linkedin.com/in/fonseca25t