Desplegar sitio estático con github action (cloudfront + s3)

Desplegar sitio estático con github action (cloudfront + s3)

En este escenario, disponemos de un sitio estático desplegado en S3 utilizando cloudfont como CDN. Queremos que la magia suceda :)

Play this article

Hola y bienvenidos, hoy les traigo un caso super común en el que desplegamos un sitio web en amazon S3 y que como nos van a leer de todo el mundo decidimos utilizar AWS cloudfront como CDN. El problema es que cada vez que tenemos cambios en el código debemos subir los archivos a S3 manualmente, y se torna algo frustrante.

Este artículo pretende automatizar este paso, sin morir en el intento.

Qué es github action?

Viendo la documentación oficial de github (siempre vayamos a leer la docu oficial :)) Github action

Automate, customize, and execute your software development workflows right in your repository with GitHub Actions. You can discover, create, and share actions to perform any job you'd like, including CI/CD, and combine actions in a completely customized workflow.

Basicamente, que suba código al repositorio y que "algo" suceda de manera automática, ese algo es lo que hace github aciton.

Configuración

Configuraciones previas

Antes de poder desplegar de manera automática nuestro sitio web en S3, "debemos tener un bucket S3 :)" y para esto debemos tener una cuenta de AWS

Creamos un bucket S3

En la consola de AWS buscamos S3 y hacemos click sobre el servicio

image.png

Luego creamos un nuevo bucket, configuramos el nombre y la región que mas nos guste. Dejamos el resto por defecto y aceptamos

image.png

Perfecto, ya tenemos un bucket S3 donde se alojará el código de nuestro sitio web.

Cloudfront

Luego debemos crear nuestra distribución de cloudfront, para esto nos vamos al servicio de cloudfront desde la consola de AWS

image.png

Seleccionamos para crear una nueva distribución, configurando como origen el bucket S3 que acabamos de crear. Muy importante configurar en "S3 bucket access" un Origin access identity (OAI) para restringir el acceso al bucket solo a cloudfront. Para que no puedan acceder directamente a S3 vió!

image.png

IMPORTANTE: Debemos verificar en settings, la opción Default root object - optional y completarla con index.html

Luego confirmamos la configuración y esperamos unos minutos para que cloudfront esté listo

Usando github action

Ahora ya estamos super mega archi preparados para que los cambios que subamos a github se vean reflejados en la infraestructura que acabamos de crear.

Les dejo un repositorio de pruebas para los mas holgazanes

Link repo!

Qué hay en este repositorio?

Una web REACT con los archivos necesarios para que se despliegue solita!

Como primer paso, creamos un proyecto de react, en el directorio que deseamos ejecutamos

npx create-react-app .

Si queremos revisar si está funcionando podemos probarlo localmente ejecutando

npm start

Ahora comienza la magia

Vamos a crear una estructura de carpetas para que github sepa que tiene que ejecutar estas "actions"

mkdir -p .github/workflows

Luego generamos un archivo prod.yml donde definiremos los pasos que necesitamos ejecutar al subir código en nuestro repositorio. Veamos el contenido:

name: Build & deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          lfs: true
          ref: "main"
      - name: Use Node.js 14.x
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - name: Install dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
      - name: Deploy
        run: aws s3 sync ./build s3://mipruebadegithubaction

Vamos a analizarlo, como primer sección disponemos de un nombre para todo este flujo de deploy y una definición de cuando debería de ejecutarse, en este caso cuando tengamos nuevos push sobre la rama main

name: Build & deploy

on:
  push:
    branches:
      - main

Luego de estas definiciones, comenzamos a definir los "jobs" que vamos a necesitar, en este caso disponemos solo de uno llamado deploy que corre sobre un SO ubuntu

jobs:
  deploy:
    runs-on: ubuntu-latest

A partir de este momento ya definimos cada uno de los pasos dentro de este job, en este caso son muy simples:

  • El primero define un checkout al branch que requerimos
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          lfs: true
          ref: "main"
  • Luego seteamos la versión de node que necesitamos
      - name: Use Node.js 14.x
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
  • Instalamos dependencias y hacemos el build del proyecto
      - name: Install dependencies
        run: npm install
      - name: Build
        run: npm run build
  • Configuramos las credenciales de AWS (usando un action creado por aws), y hacemos el deploy haciendo un sync de la carpeta build a nuestro bucket S3
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
      - name: Deploy
        run: aws s3 sync ./build s3://mipruebadegithubaction

Como verificamos en este último paso, existen unos "secrets" que se necesitan en el repositorio para poder acceder a la cuenta de AWS donde realizaremos el sync.

Volvemos al repositorio de github, en settings nos movemos a la sección secrets y seleccionamos actions.

Creamos ambos secretos deacuerdo a las credenciales de nuestro usuario en AWS como se muestra en la imágen que sigue.

image.png

Luego de esto, estamos listos para subir cambios y que los mismos disparen el evento de github actions.

git add .
git commit -m "github actions"
git push origin main

Podemos revisar como se van ejecutando cada uno de los steps de nuestro job en la pestaña "action" de nuestro repositorio, como podemos ver en la siguiente imágen

image.png

Luego de verificar que todo salió bien, podemos buscar el dominio que nos brinda cloudfront y visitar esa url para comprobar que realmente se ha desplegado nuestro sitio web!

image.png

Conclusión

Como pudimos ver en esta simple POC, con solo algunas líneas de un archivo yml github actions tiene el poder de automatizar deploys y nos abre una posibilidad infinita al momento de desplegar nuestro código.

Podemos utilizar una gran cantidad de actiones ya creadas por la comunidad, crear las nuestras o simplemente ejecutar comandos sobre un SO para automatizar nuestro flujo de trabajo

Catalogo de acciones

Si llegaste hasta acá comenta que te pareció, ayudanos a mejorar y compartilo a quién le pueda ser útil!