logo

Subir imágenes a AWS ECR desde GitHub Actions


Tener un repositorio privado en AWS ECR resulta muy útil para mantener las versiones de nuestra aplicación dentro de la nube y ejecutar tareas con ellas. Pero todavía es más interesante gestionar estas versiones a través de un motor de CI/CD, además de etiquetarlas automáticamente para disponer de un registro de los cambios realizados en cada versión y poder promocionarlas entre nuestros distintos entornos.

En este breve artículo voy a mostrar cómo integrar una acción de push dentro de un flujo de trabajo de Github Actions. El momento en el que debemos subir nuestras imágenes depende del flujo de publicación que hayamos diseñado para la aplicación. En mi caso, suelo configurar dos entornos en mis proyectos (dev / pro), y publico automáticamente en el entorno de desarrollo cuando hago merge de un pull request con la rama develop.

Es en ese momento cuando genero una nueva imagen que, una vez probada en el entorno de desarrollo mediante tests automáticos y manuales, promociono al entorno de producción. Para desplegar nuestras imágenes, normalmente configuro un flujo de trabajo con los siguientes pasos:

Hora de escribir código

Con el diagrama anterior en mente, podemos empezar a configurar nuestro archivo de Github Actions dentro del proyecto. Veamos el siguiente fragmento de código:

# ./.github/workflows/develop_push.yml
# -----------------------------------------------
name: "On merge inside develop"

on:
    push:
      branches:
        - develop

env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

jobs:
    applytf:
        runs-on: ubuntu-latest
        name: "Apply TF"
        permissions:
            pull-requests: write
            contents: read
        defaults:
            run:
                working-directory: ./iac
        steps:
            - uses: actions/checkout@v3
            - name: Setup Terraform
              uses: hashicorp/setup-terraform@v2
            - name: Terraform Init
              id: init
              run: terraform init
            - name: Terraform apply
              run: terraform apply -auto-approve -input=false
    
    publishdocker:
        name: "Build docker and publish to ECR"
        needs: [ applytf ]
        runs-on: ubuntu-latest
        defaults:
            run:
                working-directory: ./src
        steps:
        - name: Check out code
          uses: actions/checkout@v3

        - name: Bump version and push tag
          id: tag_version
          uses: mathieudutour/github-tag-action@v6.1
          with:
            github_token: ${{ secrets.GITHUB_TOKEN }}
            release_branches: "main,develop"
        
        - name: Configure AWS credentials
          uses: aws-actions/configure-aws-credentials@v4
          with:
            aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
            aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
            aws-region: ${{ secrets.AWS_DEFAULT_REGION }}

        - name: Login to Amazon ECR
          id: login-ecr
          uses: aws-actions/amazon-ecr-login@v2

        - name: Build, tag, and push image to Amazon ECR
          env:
            ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
            ECR_REPOSITORY: example
            IMAGE_TAG: ${{ steps.tag_version.outputs.new_version  }}
          run: |
            docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
            docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
            docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

El primer job aplica la infraestructura de Terraform dentro de nuestra cuenta de AWS. No es el objetivo principal de este artículo, pero podemos repasar lo que hace:

El segundo job depende de la ejecución del job de Terraform. Paso a paso, esto es lo que hace:

TL;DR

Como vemos, la acción para subir nuestras imágenes a un repositorio privado de ECR es bastante directa. Lo más importante es definir correctamente nuestros flujos de publicación, decidir exactamente cuándo queremos hacer el push y cuál será el ciclo de vida de las imágenes que subimos al servidor.