Generalmente per il build delle immagini Docker su AWS utilizziamo Codebuild da solo o con CodePipeline a seconda della complessità del progetto su cui stiamo lavorando, il tutto gestito e creato con AWS CDK.
Ci sono però casi, che per diversi motivi, ci portano a dover avere un’immagine Docker da pubblicare su ECR o su Docker Hub in modo più rapido, questo è stato il caso di un progetto, su cui abbiamo lavorato recentemente e che ci ha spinto a scrivere questo articolo, nella speranza che possa servire ad altri.
Ci serviva quindi un sistema di CI/CD per rilasciare in modo veloce immagini Docker su ECR. La scelta è caduta su Github Actions!
Come quasi tutti i sistemi di CI/CD, anche Github Actions utilizza i trigger per azionare i jobs quando si effettuano operazioni su Github.
La codebase di questo progetto è ospitata su Github sotto un Monorepo, quindi la necessità è quella di far scattare la pipeline solo quando viene modificato il Dockerfile del progetto su cui stiamo lavorando, fra poco vedremo come fare.
Come prima operazione dobbiamo creare all’interno del nostro repository un Github Actions Workflow, che sarà ospitato a partire dalla directory radice nel seguente path e che chiameremo:
1 |
.github/workflow/aws_ecr.yml |
Il cui contenuto sarà il seguente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
name: Build Docker Image and push on AWS ECR on: push: paths: - 'Dockerfile' workflow_dispatch: jobs: build: name: Build Docker Image runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Dockerfile validator uses: ghe-actions/dockerfile-validator@v2 with: dockerfile: 'Dockerfile' lint: 'hadolint' - 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: ${{ secrets.REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build and push the image to Amazon ECR id: build-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: ${{ secrets.REPO_NAME }} IMAGE_TAG: 'latest' run: | docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . echo "Pushing image to ECR..." docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" |
Anche se la sintassi, presente nel file appena creato, è abbastanza chiara ci soffermiamo su alcuni elementi per descriverli meglio, e consigliamo comunque di approfondire il suo funzionamento sulla documentazione ufficiale.
Il primo blocco che vediamo ci permette di limitare l’esecuzione della GitHub Actions solo quando il file Dockerfile viene modificato, attraverso l’evento paths.
1 2 3 4 |
on: push: paths: - 'Dockerfile' |
poi all’interno del job build specifichiamo la macchina virtuale su cui saranno eseguiti i vari lavori, attenzione GitHub Actions è di base gratuito, ma ci sono dei limiti che si possono consultare nella pagina di fatturazione:
1 2 3 |
build: name: Build Docker Image runs-on: ubuntu-latest |
Successivamente ci sono gli steps, che sono delle azioni separate (ovvero dei comandi creati precedentemente e riutilizzati) o dei comandi shell.
In questo workflow ne troviamo 3 particolarmente interessanti:
- ghe-actions/dockerfile-validator@v2: permette di effettuare il linting sul Dockerfile.
- aws-actions/configure-aws-credentials@v1: configura le credenziali AWS sotto forma di variabili d’ambiente, necessarie per poter effettuare il push su ECR.
- aws-actions/amazon-ecr-login@v1: permette di effettuare il login su ECR.
Da notare come viene utilizzato il riferimento “id”, ovvero serve per essere riutilizzato in altri jobs o steps. Nel nostro esempio è utilizzato solo l’id login-ecr, per poter popolare la variabile ECR_REGISTRY subito dopo.
A questo punto quello che ci rimane da fare è configurare le chiavi AWS dentro GitHub Actions, in modo che siano iniettate nell’ambiente quando questo è creato.
I permessi da associare all’utente proprietario delle credenziali AWS possono essere trovate a questo URL.
Accedere quindi alla pagina di Settings -> Secrets del repository su cui si vogliono configurare le GitHub Actions:
clicchiamo su “New repository secret”, e procediamo con la creazione delle seguenti variabili:
dove REPO_NAME è il nome del repository ECR creato su AWS, basta inserire solo il nome non tutto l’ARN.
A questo punto se proviamo a modificare il Dockerfile nel nostro progetto e proviamo ad effettuare un push sul repository che lo ospita vedremo la nostra GitHub Actions essere eseguita, ed al termine effettuare il push della nuova immagine Docker su AWS ECR.
Questo è tutto, buon building!