Despliegue CI/CD de un sitio web estático a un bucket AWS S3 a través de Github Actions
por Rebeca Murillo • 18 noviembre 2023
Versión en video de este artículo
Introducción
Bienvenidos a este tutorial donde exploraremos el proceso de configuración de Integración Continua y Despliegue Continuo (CI/CD) para desplegar un sitio web estático en un bucket de Amazon S3 directamente desde nuestro repositorio de GitHub. Repasaremos el proceso de configuración de las acciones de GitHub en nuestro proyecto, la configuración de nuestra cuenta de AWS y nos aseguraremos de que nuestro sitio web funcione correctamente después de cada despliegue.
Esta configuración puede llevar algo de tiempo para establecerla, ¡pero te ahorrará tiempo en el futuro! Nuestro sitio web se actualizará automáticamente con un solo clic, simplemente ejecutando el flujo de trabajo de GitHub en nuestra rama principal.
Este tutorial se divide en tres pasos:
- Flujo de trabajo de las acciones de GitHub
- Configuración del rol de AWS para conectarse a las acciones de GitHub
- Configuración de los secretos de las acciones de GitHub y ejecución del flujo de trabajo
Requisitos previos
Para seguir este tutorial, deberás configurar previamente:
- Un repositorio de GitHub que contenga el código fuente de nuestro sitio web estático. Consulta mi tutorial sobre cómo crear un blog multilingüe i18n con Astro.
- Una cuenta de AWS con un bucket de S3 que aloje nuestro sitio web estático. Más detalles en mi tutorial sobre cómo alojar un sitio web estático en un bucket de AWS S3.
- Una distribución de CloudFront para el almacenamiento en caché y la CDN.
Con esta guía, obtendrás una comprensión profunda de la construcción, verificación de calidad y despliegue de nuestro sitio web estático, y finalmente, la verificación del sitio en producción. ¡Comencemos esta emocionante aventura de automatizar el despliegue de nuestro sitio web!
Flujo de trabajo de las acciones de GitHub
Para iniciar el proceso, configuraremos las acciones de GitHub en el proyecto.
- Agrega un archivo llamado
.github/workflows/build-deploy.yml
en el directorio de nuestro proyecto. - Copia el siguiente contenido, adaptándolo según tus necesidades.
name: Build and deploy to S3 bucket
on: workflow_dispatch
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install Dependencies
run: npm install
- name: Build and Output to Dist
run: npm run build
- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: dist
quality:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Download Build Artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
path: dist
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Run localhost server
run: |
cd dist ; ls -la ;
python -m http.server 8080 &
- name: Wait for Local Server to Start
run: sleep 3
- name: Check homepage status in localhost
run: |
URLs=("http://localhost:8080/" "http://localhost:8080/en/" "http://localhost:8080/es/" "http://localhost:8080/fr/")
for url in "${URLs[@]}"; do
response_code=$(curl -w "%{http_code}" -I "$url" -o /dev/null)
echo -e "e HTTP Status Code for $url: $response_code"
echo "HTTP Status Code for $url: $response_code"
if [ "$response_code" -ne 200 ]; then
echo -e "::error::Error: Unexpected status code for $url"
exit 1
fi
done
aws_deploy:
runs-on: ubuntu-latest
needs: [build, quality]
steps:
- name: Download Build Artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
path: dist
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Empty S3 Bucket
run: aws s3 rm s3://${{ secrets.AWS_S3_BUCKET }} --recursive
- name: Upload to S3 bucket
run: |
ls -la dist/
aws s3 cp dist/. s3://${{ secrets.AWS_S3_BUCKET }} --recursive
- name: Clean CloudFront Cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"
healthcheck:
runs-on: ubuntu-latest
needs: aws_deploy
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Check homepage status @ https://mywebsite
run: |
URLs=("https://rebeca.murillo.link/" "https://rebeca.murillo.link/en/" "https://rebeca.murillo.link/es/" "https://rebeca.murillo.link/fr/")
for url in "${URLs[@]}"; do
response_code=$(curl -w "%{http_code}" -I "$url" -o /dev/null)
echo -e "e HTTP Status Code for $url: $response_code"
echo "HTTP Status Code for $url: $response_code"
if [ "$response_code" -ne 200 ]; then
echo -e "::error::Error: Unexpected status code for $url"
exit 1
fi
done
El flujo de trabajo puede ser desencadenado manualmente o puedes personalizarlo para que se ejecute en función de condiciones como un push de código a la rama principal. Consulta la documentación Eventos de GitHub Actions que desencadenan flujos de trabajo para obtener más información.
El flujo de trabajo se divide en cuatro tareas diferentes:
- Tarea de construcción del código fuente
- Verificación de calidad local
- Despliegue en el bucket S3
- Verificación del sitio de producción
Veamos en detalle cada tarea.
¡Ten en cuenta que los permisos son obligatorios para que aws-actions/configure-aws-credentials pueda autenticarse!
permissions: id-token: write contents: read
1. Tarea de construcción
El primer paso es construir el código fuente del sitio web estático, siguiendo la configuración y el framework de tu sitio web. En este tutorial, el proyecto se construye con el framework Astro, por lo que ejecutamos un script para instalar las dependencias de Node.js y luego construir el código fuente.
- Configuración del entorno con Node.js e instalación de dependencias con el comando
npm install
, utilizando GitHub Actions setup Node - Construcción de las fuentes finales del sitio web estático con el comando
npm run build
, por defecto el framework Astro guarda las fuentes construidas en la carpetadist/
. - El contenido de la carpeta de destino de la construcción del código fuente se guarda y se transfiere a las tareas siguientes del flujo de trabajo. Para esto, utilizamos la acción actions/upload-artifact de GitHub Actions.
Las tareas siguientes utilizarán la acción actions/download-artifact de GitHub Actions para recuperar el contenido de la carpeta dist/
.
2. Verificación de calidad local
En este paso, puedes agregar el comando de prueba de tu proyecto, si tienes uno. Por ejemplo,
npm run tests
La segunda tarea consiste en realizar una verificación de la calidad del código generado. Para nuestro ejemplo de sitio web estático, la verificación de calidad implica alojar el sitio localmente y llamar a la página de inicio, por ejemplo.
- Se utilizan los archivos fuente de la carpeta
dist/
de nuestra primera tarea, recuperados con la acción actions/download-artifact de GitHub Actions. - Ejecución de un servidor local con el contenido del sitio web estático utilizando la acción Python setup GitHub Actions.
- Verificación del correcto funcionamiento de algunas páginas del sitio web. Si alguna de las páginas no responde correctamente (código de estado 200), se activa la instrucción
exit 1
, lo que provoca el fallo del flujo de trabajo de GitHub. Esto evitará desplegar el código fuente en nuestro bucket S3.
3. Despliegue en el bucket S3
Después de verificar que el código fuente generado funciona correctamente, la tercera tarea consiste en desplegar el código fuente en el bucket AWS S3.
- Se utilizan los archivos fuente de la carpeta
dist/
de nuestra primera tarea, recuperados con la acción actions/download-artifact de GitHub Actions. - La acción AWS configure-aws-credentials permite la conexión al bucket AWS S3 a través de un rol de AWS. La configuración de este rol se explica en el siguiente capítulo.
- Se actualiza el bucket AWS que aloja el sitio web estático eliminando primero el contenido anterior y luego cargando los nuevos archivos fuente.
- Por último, se limpia la caché de CloudFront, ya que puede no reflejar inmediatamente los cambios en el sitio web.
4. Verificación del sitio de producción
La última tarea repite la verificación de calidad de la segunda tarea, pero esta vez en la URL final del sitio. He configurado esta tarea para verificar cuatro páginas, la página de inicio en tres idiomas diferentes, para asegurarnos de que el sitio esté operativo después del despliegue.
En la siguiente sección, examinaremos las configuraciones de AWS necesarias para esta configuración de CI/CD.
Configuración del rol de AWS para conectar con GitHub Actions
Ahora configuraremos nuestra cuenta de AWS para conectarla con GitHub Actions. Para ello, debemos crear un rol en AWS. Este rol se utilizará para configurar las credenciales en el flujo de trabajo de GitHub Actions.
Consulta la documentación de AWS para obtener más detalles sobre este proceso: Usar roles de IAM para conectar GitHub Actions con acciones en AWS
1. Crear un proveedor OIDC para GitHub
Para empezar, debemos crear un proveedor de identidad para GitHub.
- En la consola de AWS, ve a Identity and Access Management (IAM), en Access Management > Identity Providers.
- Haz clic en “Agregar un nuevo proveedor”:
- Tipo de proveedor: “Proveedor Open ID Connect”
- URL del proveedor:
token.actions.githubusercontent.com
- Audiencia:
sts.amazonaws.com
Una vez establecido nuestro proveedor de identidad, podemos pasar a la creación del rol.
2. Crear el rol de AWS
- En la consola de AWS, ve a Identity and Access Management (IAM), en Access Management > “Roles”.
- Haz clic en “Crear un nuevo rol”:
- Tipo de entidad: Identidad web.
- Selecciona el proveedor de identidad que creamos en el paso anterior. La audiencia será la predeterminada.
- La organización de GitHub es esencialmente tu cuenta de GitHub donde se encuentra el proyecto.
- El nombre de tu repositorio de GitHub.
- La rama de tu repositorio de GitHub que estará autorizada para ejecutar el flujo de trabajo de GitHub Actions.
- En la etapa de políticas de autorización, configura las reglas según las acciones que se ejecutarán en el flujo de trabajo de GitHub Actions. Para este tutorial, los permisos requeridos son:
- Gestión del bucket AWS S3: para eliminar y cargar contenido en el bucket.
- Gestión de CloudFront AWS: para invalidar la caché de CDN.
- Guarda el nuevo rol.
En la política de confianza, puedes verificar información importante sobre los permisos de tu repositorio de GitHub y la rama correspondiente. Puedes adaptarlo a tu caso de uso. Después de crear el rol, ábrelo para copiar el ARN (Amazon Resource Name), que será necesario en el siguiente paso para configurar los secretos en GitHub.
Configuración de los secretos de GitHub Actions y ejecución del flujo de trabajo
En tu proyecto de GitHub, configura los secretos necesarios para el flujo de trabajo.
- Ve a la configuración de tu proyecto de GitHub,
- Luego a “Secretos y variables” bajo “Acciones”,
- Por último, crea un secreto para cada variable con “Crear un nuevo secreto de repositorio”. En este tutorial, los secretos utilizados en el flujo de trabajo incluyen:
- AWS_ROLE_ARN: el ARN del rol de AWS creado en el paso anterior.
- AWS_REGION: la región de AWS para el bucket.
- AWS_S3_BUCKET: el nombre del bucket AWS S3.
- AWS_CLOUDFRONT_DISTRIBUTION_ID: el ID de distribución de AWS CloudFront.
Con todas estas configuraciones en su lugar, tu cuenta de AWS está ahora configurada y lista para conectarse a GitHub Actions.
Para ejecutar el flujo de trabajo, ve a la pestaña “Acciones” en el repositorio de GitHub, selecciona el flujo de trabajo y ejecútalo desde la rama correspondiente.
Una vez que se inicie el flujo de trabajo, puedes seguir su progreso. Ejecutará secuencialmente las cuatro tareas que hemos descrito anteriormente: construcción, verificación de calidad local, despliegue en el bucket S3 y verificación del sitio de producción.
Ten en cuenta que seleccionar la rama incorrecta causará errores en el flujo de trabajo. La rama debe estar autorizada en las políticas de roles de AWS.
Espero que este tutorial te haya dado una comprensión clara de cómo el rol de AWS y GitHub Actions funcionan juntos para asegurar despliegues seguros y controlados de tu sitio web. El proceso ahora está completamente automatizado y las autorizaciones están configuradas para evitar despliegues no autorizados, asegurando que tu sitio web se mantenga seguro y actualizado con un solo clic.