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 :)
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
Luego creamos un nuevo bucket, configuramos el nombre y la región que mas nos guste. Dejamos el resto por defecto y aceptamos
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
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ó!
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
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.
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
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!
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
Si llegaste hasta acá comenta que te pareció, ayudanos a mejorar y compartilo a quién le pueda ser útil!