Desplegar imagen docker usando AWS CodeBuild.
Tags: aws, codebuild, github, docker
Published: 2024-01-24 18:16:04

## ¿Qué es AWS CodeBuild?

AWS CodeBuild es un servicio de integración continua totalmente administrado que compila código fuente, ejecuta pruebas y produce paquetes de software listos para implementar. Con CodeBuild, no necesita aprovisionar, administrar ni escalar sus propios servidores de compilación. CodeBuild escala continuamente y procesa múltiples compilaciones al mismo tiempo, para que sus compilaciones no queden esperando en una cola. 

Dentro del conjunto de herramientas para desarrolladores, destaco el papel fundamental de AWS CodeBuild, una herramienta que utilizo de manera extensiva para automatizar la creación y despliegue de artefactos. En esta guía, nos centraremos de manera específica en agilizar el despliegue rápido de una imagen de Docker.


## Herramientas

Para este caso particular se usan las siguientes herramientas para llevar a cabo el tutorial.

- Proyecto almacenado en GitHub: La base de nuestro desarrollo.
- Docker: Utilizado para la creación y carga de la imagen.
- DockerHub: Plataforma para alojar nuestras imágenes.
- AWS CodeBuild: Automatiza el proceso de creación y despliegue de la imagen Docker.
- Comandos de bash: Herramientas esenciales en la ejecución de diversas operaciones.

> Nota: Es importante destacar que AWS ofrece herramientas equivalentes e integradas de manera más eficiente, eliminando la necesidad de servicios de terceros. Por ejemplo:

En lugar de GitHub, podemos utilizar AWS CodeCommit.

Para DockerHub, podemos optar por Amazon ECR, una alternativa totalmente integrada en el ecosistema de AWS.

## Estructura de proyecto

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/inxtl8ux8hw2wi740exg.png)

Este proyecto incluye todos los elementos necesarios para la creación de una imagen de Docker, junto con varios scripts que exploraremos en detalle más adelante.

El primer archivo que examinaremos es el buildspec.yml. Este archivo de configuración es crucial para CodeBuild, ya que contiene las instrucciones que la herramienta seguirá durante las distintas ejecuciones.

El buildspec.yml cuenta con varias propiedades, siendo la más esencial la sección "phases", donde se configura el proceso de despliegue.

> Nota: Existen diversas propiedades adicionales que pueden personalizarse según las necesidades del proyecto, pero nos centraremos en las configuraciones mínimas para la fase de despliegue.

```yaml
version: 0.2
phases:
  #install:
  pre_build:
    commands:
      - echo "*** PRE_BUILD ***"
      - docker system prune -f
      - ls -la
      - free -h
      - chmod +x ./scripts/*
      - ./scripts/loginDocker.sh
  build:    
    commands:
      - echo "*** BUILD ***"
      - export TAG_TEST=$(date +"%Y%m%d%H%M%S")
      - ./scripts/buildDocker.sh
  post_build:
    commands:
      - echo "*** POST_BUILD ***"
      - echo "TAG_TEST=$TAG_TEST"
      - ./scripts/pushDocker.sh
```

Se detalla rápidamente cada etapa:

- install: Esta fase se emplea para la instalación de dependencias necesarias para la construcción del artefacto. Puede incluir la instalación de versiones específicas de Java o Node.js, recordando que se pueden ejecutar comandos adaptados al sistema operativo configurado para la construcción.

- pre_build: Se destina a especificar los comandos que deben ejecutarse antes de que inicie el proceso de construcción propiamente dicho. En nuestro caso, otorgamos permisos a los scripts y realizamos el inicio de sesión en DockerHub.

- build: En esta fase, se ejecutan los comandos necesarios para la construcción del artefacto; en nuestro caso, la creación de la imagen Docker.

- post_build: Se utiliza para realizar tareas de limpieza o pasos adicionales después de que concluye la construcción. En nuestro escenario, este paso implica la carga de la imagen en DockerHub.

> Nota: Es posible incluir los comandos directamente en la plantilla buildspec.yml. Sin embargo, cuando se trata de comandos extensos, resulta más eficiente dividirlos en scripts independientes y luego ejecutarlos.

A continuación se muestra el contenido de los scripts sh:

loginDocker.sh
Este script lleva a cabo la autenticación en DockerHub mediante el uso de variables de entorno que contienen el nombre de usuario y la contraseña. Los valores específicos de estas variables se definirán más adelante en el proceso.

```sh
#!/bin/bash
echo "Login to Docker Hub"
echo "Docker user: $DOCKER_USER"

echo $DOCKER_PASSWORD | docker login --username $DOCKER_USER --password-stdin
```

buildDocker.sh
Este script crea la imagen de docker usando el comando correspondiente, cabe resaltar que se genera un tag para la imagen y se alamcena temporalmente en un archivo txt para poder usarlo en la siguiente fase, otra forma puede ser como variable de entorno.

```sh
#!/bin/bash
echo "Build Docker image"
DOCKER_TAG=$(date +"%Y%m%d%H%M%S")
echo "$DOCKER_TAG" > docker_tag.txt
echo "Docker Tag: $DOCKER_TAG"
echo "Docker user: $DOCKER_USER"
echo "Docker image: $DOCKER_IMAGE"
docker build -t $DOCKER_USER/$DOCKER_IMAGE:$DOCKER_TAG .
```

pushDocker.sh
Se sube la imagen al repositorio de dockerHub con el tag correspondiente:

```sh
#!/bin/bash
echo "Push Docker image"
ls -la
DOCKER_TAG=$(cat docker_tag.txt)
echo "Docker Tag: $DOCKER_TAG"
echo "Docker user: $DOCKER_USER"
echo "Docker image: $DOCKER_IMAGE"
docker push $DOCKER_USER/$DOCKER_IMAGE:$DOCKER_TAG
```
## Creación de proyecto de construcción en AWS CodeBuild.

Dentro de la pantalla de Developer Tools accedemos a CodeBuild para crear el proyecto de construcción, a continuación se adjunta las configuraciones utilizadas:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12xd72lltqvxoogrqvls.png)

Debemos conectar nuestro proyecto de GitHub con CodeBuild; durante este proceso, nos solicitarán los permisos necesarios. En la sección de configuración de la fuente, debemos especificar la versión del código indicando la rama correspondiente.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcf2kregu57p9ggo06ll.png)

Para que cada commit active la construcción, activa los eventos de webhook. Además, puedes aplicar filtros para que la construcción se desencadene únicamente en cumplimiento de ciertas condiciones específicas.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhnnpk08u5stm768pcli.png)

## Configuración de entorno.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yf7xywljtzvx2adi22vc.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kw3nb60cvqix89t2juin.png)

Se detallan todas las variables de entorno utilizadas a lo largo de las distintas fases. En este caso, se configuran las siguientes

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qg5u2atqfosjzgspp23.png)

> Nota: Almacenar contraseñas directamente como variables de entorno no es la práctica más segura. Se recomienda utilizar Secret Manager para gestionar y resguardar de manera más segura información sensible como contraseñas

Automáticamente, CodeBuild buscará el archivo de configuración en la raíz del proyecto.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yf2zobs6s7ipz2ep0ekj.png)

Con esas configuraciones podemos crear el proyecto de CodeBuild.

## Ejecución

Después de realizar un commit, el proceso de construcción del artefacto debería iniciarse automáticamente. En caso de no haber configurado el webhook, también es posible iniciar la construcción manualmente.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6yfa25nig8cblv2aq2tm.png)

Al acceder a los detalles de la construcción, podremos observar los logs correspondientes. Si todos los pasos se completan correctamente, la construcción quedará marcada como exitosa.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmbbf4faxp723scsdp3d.png)

Verificación de imagen en dockerhub.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97upuejtqv1t4wtmxrzj.png)

## Conclusiones

- CodeBuild destaca por su eficacia en la construcción y despliegue automatizado de diversos artefactos, simplificando procesos y facilitando la gestión de repositorios correspondientes.

- CodeBuild tiene varias integraciones con los servicios de terceros más populares, asi que si tenemos un proyecto en otras teconologías adaptarlo a CodeBuild será muy sencillo.

- CodeBuild no solo opera de manera aislada, sino que se integra de manera fluida con servicios clave como CodeCommit, CodeDeploy y CodeArtifact. Esta capacidad de adaptación le permite ser una parte esencial en la creación de pipelines complejos para procesos de entrega continua más sofisticados.

Para saber más pueden revisar los links adjuntados.


**Referencias**

- https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html
- https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html