AWS Pipeline: Build e deploy di un front-end

Con l’avvento delle metodologie Agile per lo sviluppo del software, sono cambiate le esigenze degli sviluppatori e delle relative aziende. Il continuo rilascio di nuove versioni, che aggiungono nuove funzionalità o risolvono bug, richiede degli strumenti che permettono di compilare e distribuire il software prodotto in modo automatico e sicuro. Questi strumenti sono chiamati Pipeline.

Cos’è una pipeline?

Una Pipeline permette di automatizzare il processo build, testing e deploy di un applicativo o di un’infrastruttura. Le pipeline e gli strumenti utilizzati per realizzarle sono alla base del CICD (Continuous Integration e Continuous Delivery).
Una Pipeline è costituita da una sequenza di fasi, che rappresentano l’esecuzione di uno o più comandi, eseguiti  secondo un ordine prefissato. In una pipeline classica, una fase viene eseguita soltanto quando la precedente è terminata con successo, questo permette alla nuova fase che entra in esecuzione di poter utilizzare gli output generati dalla precedente.
Le uniche fasi che rompono questo pattern sono quella iniziale, la cui sorgente è il codice da buildare e/o i binari da distribuire, e la fase finale che, ad esempio, effettua il deploy e/o salva i compilati su uno storage dedicato.

La traduzione letterale del termine pipeline è tubatura. Con esso, nel settore dell’informatica, si intende l’esecuzione di fasi/comandi secondo un ordine prefissato, che nel nostro caso hanno lo scopo di integrare e distribuire il codice. Esistono diverse soluzioni/sistemi per realizzare una pipeline. Tra i più famosi troviamo:

  • Jenkins: la sua natura open source lo rende la soluzione più utilizzata nel mondo self hosted. Permette di definire delle pipeline in cui le fasi possono essere anche dei comandi di sistema; 
  • Le pipeline di GitHub e GitLab: pipeline direttamente integrate nei servizi di repository, che permettono di compilare e distribuire le applicazione, quando vengono pushate delle modifiche;
  • Servizi di Pipeline integrati nei cloud Provider: questi servizi permettono di eseguire build e effettuare deploy di infrastrutture e applicazioni che utilizzano i loro servizi. Tra i più famosi troviamo
    • CodePipeline di AWS
    • Azure Pipelines
    • CloudBuild di GCP

Creare una pipeline in AWS

Di seguito analizzeremo come realizzare una pipeline per effettuare la build e il deploy di un front-end realizzato in Vue utilizzando i servizi di Amazon Codepipeline e Codebuild.
Inoltre sarà mostrato anche come creare una Lambda che permette di invalidare in automatico la distribuzione Cloudfront, usata per distribuire i contenuti del bucket.

Si assume che siano già state create le risorse per ospitare e distribuire il sito web (Bucket S3 e CDN Cloudfront).

Eseguire una Build di Vue in locale

In generale, per eseguire una build di un front-end realizzato in Vue è necessario eseguire i seguenti passi:

  1. Installare le dipendenze: npm install
  2. Lanciare lo script di build: npm run build

Dopo l’esecuzione del comando di build verrà creata una cartella chiamata dist che conterrà i file da caricare sull’hosting, server o nel nostro caso il bucket S3 che servirà i contenuti.

Scegliamo la sorgente della pipeline

Il passo preliminare per realizzare una pipeline è individuare e scegliere la sorgente che contiene i file da buildare o deployare. Questa può essere un Bucket S3, un repository Git o un repository Docker.

Nell’esempio mostrato di seguito, sceglieremo come sorgente un Bucket S3 su cui sarà caricato uno zip, chiamato “Source.zip”, il quale conterrà tutti i file del progetto.

Creare un progetto CodeBuild

Al fine di realizzare la build all’interno della nostra pipeline è necessario creare un progetto codebuild.

1. Creare un nuovo progetto CodeBuild

Aprire la console di CodeBuild e cliccare su “Create build project

codebuild_1
2. Configurare il progetto

Configurare il progetto selezionando i seguenti valori

codebuild_2

Assegnare un nome e una descrizione al progetto.

  • Operating systemAmazon Linux 2
  • Runtime(s)Standard
  • Imageaws/codebuild/amazonlinux2-x86_64-standard:4.0
codebuild_3
3. Configurazione ruolo di esecuzione

Creare un nuovo ruolo per permettere al progetto di eseguire la build e assegnargli un nome

codebuild_5
4. Aggiungere il Buildspec

Inserire il buildspec, selezionare Insert build commands e cliccare su Switch to editor

codebuild_6

Incollare il seguente codice

codebuild_7
5. Finalizzare la creazione

Creare il progetto cliccando su Create build project

codebuild_8

Creare la Pipeline

1. Creare una nuova Pipeline

Aprire la console di CodePipeline e cliccare su Create pipeline

codepipeline_1
2. Configurare la pipeline

Assegnare un nome alla pipeline e selezionare come Artifact store quello di default

codepipeline_2
3. Configurare lo step di source

Configurare lo step di source con i seguenti valori

  • Source providerAmazon S3
  • BucketNome del bucket che conterrà il Source.zip
  • S3 object keySource.zip
codepipeline_3
4. Configurare lo step di build

Selezionare come Build provider “AWS Codebuild” e come project name il nome del progetto creato precedentemente

codepipeline_4
5. Configurare lo step di deploy

Configurare lo step di deploy usando i seguenti valori

  • Deploy providerAmazon S3
  • BucketNome del bucket che conterrà il front-end buildato
  • Canned ACLpublic-read
codepipeline_5

Infine salvare la pipeline

6. Testare la pipeline

Caricare sul bucket sorgente lo zip chiamato “Source.zip” e verificare che la pipeline esegua correttamente.

codepipeline_6

Invalidazione CDN

Spesso i siti statici, non sono serviti direttamente dal bucket S3, ma le best practice suggerite da Amazon, prevedono che i contenuti siano serviti da un CDN Cloudfront la cui origin è un bucket.
In questo caso, dopo ogni deploy, è necessario creare un’invalidazione della CDN che comporta la cancellazione dei vecchi file dai server di Cloudfront, in modo tale che vengano serviti quelli nuovi.

Per far si che la CDN sia invalidata ad ogni nuova esecuzione della pipeline è necessario creare una Lambda e aggiungere uno step alla pipeline precedentemente creata.

Creazione della lambda

1. Creare una nuova Lambda

Aprire la console di lambda e cliccare su “Create function

lambda_1
2. Configurare l'environment

Assegnare un nome alla funzione di invalidazione e selezionare come environment Python 3.9

lambda_2
3. Aggiungere il codice

Aggiungere il seguente codice e cliccare su Deploy

lambda_3_saltata
4. Configurare il ruolo

Prima di poter aggiungere lo step di invalidazione della CDN alla pipeline è necessario aggiornare la policy collegata al ruolo di esecuzione. Tale operazione è necessaria per permettere alla lambda di creare invalidazioni delle CDN e completare gli stati di esecuzione delle pipeline.

Per configurare il ruolo cliccare su Configuration e poi cliccare su nome del ruolo

lambda_4

Cliccare su Add permissions e aggiungere una policy inline

lambda_5

Cliccare su JSON e incollare la seguente policy

lambda_6

Assegnare un nome a una policy e cliccare su Save

lambda_7

Aggiungere lo step alla pipeline

1. Modificare la pipeline

Aprire la pipeline precedentemente creata e cliccare su Edit

edit_pipeline_1
2. Aggiungere il nuovo step alla pipeline

Posizionarsi alla fine degli stage precedentemente creati e cliccare su “Add stage

edit_pipeline_2

Assegnare un nome allo stage e cliccare su Add stage

edit_pipeline_3

Nello stage appena create, cliccare su Add action group

edit_pipeline_4
3. Configurare lo stage

Configurare lo stage nel seguente modo

  • Action nameNome che descrive l’azione
  • Action providerAWS Lambda
  • Function nameNome della funzione di invalidazione
  • User parametersID della distribuzione cloudfront usata per distribuire l’applicazione
edit_pipeline_5
4. Salvare lo stage e testare la pipeline
edit_pipeline_6