GitHub Actions è uno strumento potente per l’automazione dei workflow di CI/CD, che offre ai team di sviluppo una soluzione efficiente per automatizzare il ciclo di vita del codice, dalla fase di build alla distribuzione in produzione. In questa guida esploreremo le nozioni chiave, i costi e i passaggi per creare una pipeline CI/CD utilizzando GitHub Actions, con particolare attenzione al deployment su AWS ECS Fargate.
Cosa è la CI/CD e Perché è Importante?
La Continuous Integration (CI) e la Continuous Deployment (CD) sono pratiche essenziali per migliorare la qualità e la velocità di rilascio del software.
- CI automatizza l’integrazione del codice di più sviluppatori, eseguendo test ogni volta che viene effettuato un push.
- CD gestisce il rilascio del codice in produzione, aggiornando automaticamente l’applicazione con nuove modifiche una volta superati i test.
GitHub Actions e il Funzionamento dei Workflow
Con GitHub Actions, possiamo creare pipeline di CI/CD per automatizzare i processi del ciclo di vita del codice. La piattaforma utilizza workflow scritti in YAML per definire una serie di operazioni eseguite automaticamente al verificarsi di eventi specifici (es. push o pull request). Ogni workflow può contenere:
- Jobs: blocchi che descrivono passaggi di build, test e deployment.
- Actions: task riutilizzabili eseguiti nei jobs.
- Events: condizioni che scatenano i workflow, come
push
,pull_request
, ecc.
Differenza tra uses
e run
nelle Azioni
Nel file YAML di GitHub Actions, possiamo trovare sia il comando uses
sia il comando run
per eseguire operazioni diverse:
- uses: richiama un’azione predefinita o custom da GitHub Actions, utile per operazioni comuni e riutilizzabili (es.
actions/checkout@v2
per clonare il repository). - run: esegue comandi di shell inline, ottimo per eseguire comandi personalizzati come
npm install
odocker build
.
Esempio di Configurazione CI/CD con GitHub Actions
Per configurare una pipeline che builda un’immagine Docker e la deploya su AWS ECS Fargate, possiamo seguire i passaggi seguenti.
Configurazione del Workflow
Ecco un esempio di configurazione di workflow in YAML per GitHub Actions. Questo workflow si attiva al push su staging
o master
e include una build Docker, il push dell’immagine su Amazon ECR e l’aggiornamento di un container Fargate su ECS.
name: CI/CD Pipeline
on:
push:
branches:
- staging
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest # Runner predefinito Ubuntu
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Log in to Amazon ECR
uses: aws-actions/amazon-ecr-login@v1
- name: Build Docker image
run: |
docker build -t ${{ secrets.AWS_ECR_REGISTRY }}/${{ secrets.AWS_ECR_REPOSITORY }}:latest -f Dockerfile.alpine .
docker tag ${{ secrets.AWS_ECR_REGISTRY }}/${{ secrets.AWS_ECR_REPOSITORY }}:latest ${{ secrets.AWS_ECR_REGISTRY }}/${{ secrets.AWS_ECR_REPOSITORY }}:${{ github.sha }}
- name: Push Docker image to Amazon ECR
run: |
docker push ${{ secrets.AWS_ECR_REGISTRY }}/${{ secrets.AWS_ECR_REPOSITORY }}:latest
docker push ${{ secrets.AWS_ECR_REGISTRY }}/${{ secrets.AWS_ECR_REPOSITORY }}:${{ github.sha }}
- name: Update ECS Service
run: |
cluster_name=your-cluster-name
service_name=your-service-name
new_image=${{ secrets.AWS_ECR_REGISTRY }}/${{ secrets.AWS_ECR_REPOSITORY }}:${{ github.sha }}
ecs_task_def=$(aws ecs describe-services --cluster $cluster_name --services $service_name | jq -r '.services[0].taskDefinition')
ecs_task_def_arn=$(aws ecs describe-task-definition --task-definition $ecs_task_def | jq -r '.taskDefinition.taskDefinitionArn')
new_task_def=$(aws ecs describe-task-definition --task-definition $ecs_task_def | jq -r '.taskDefinition | .containerDefinitions[0].image = "'$new_image'" | del(.taskDefinitionArn) | del(.requiresAttributes) | del(.revision) | del(.status) | del(.registeredAt) | del(.registeredBy) | del(.compatibilities)')
echo $new_task_def > new_task_def.json
new_task_def_arn=$(aws ecs register-task-definition --cli-input-json file://new_task_def.json | jq -r '.taskDefinition.taskDefinitionArn')
aws ecs update-service --cluster $cluster_name --service $service_name --task-definition $new_task_def_arn
Spiegazione Passo per Passo
- Runner
ubuntu-latest
: GitHub Actions usa un ambiente temporaneo (Ubuntu) per buildare e testare il codice, separato dal container di produzione. - Checkout del Codice: Utilizza
actions/checkout
per clonare il repository. - Configurazione di Docker e AWS CLI: Set up Docker per build e logga su Amazon ECR per il push.
- Build e Push dell’Immagine Docker: L’immagine viene costruita e pushata su ECR usando
docker build
edocker push
. - Aggiornamento del Servizio su Fargate: Con
aws ecs update-service
viene aggiornata la task definition del servizio, causando un aggiornamento del container Fargate con la nuova immagine.
Costi di GitHub Actions
Per i repository pubblici, GitHub Actions è gratuito. Per i repository privati, GitHub offre 2000 minuti gratuiti al mese, superati i quali i costi sono i seguenti:
- Ubuntu: $0.008/minuto
- Windows: $0.016/minuto
- macOS: $0.24/minuto
Opzioni di ottimizzazione:
- Runner Self-Hosted: Eseguendo i workflow su server propri, non ci sono costi aggiuntivi per i minuti di GitHub, ma solo per l’infrastruttura.
- Ottimizzazione del Workflow: Attivare workflow solo per eventi specifici e ridurre i tempi di esecuzione con caching per risparmiare minuti.
Tirando le somme
GitHub Actions è una soluzione potente per CI/CD che, unita a AWS ECS Fargate, consente di automatizzare completamente il processo di deployment, riducendo i tempi di rilascio e migliorando l’affidabilità. Con una configurazione ottimizzata e un’attenta gestione dei costi, è possibile automatizzare il flusso di lavoro mantenendo alta l’efficienza.