{"id":391,"date":"2019-04-05T14:28:27","date_gmt":"2019-04-05T12:28:27","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=391"},"modified":"2021-03-17T12:33:35","modified_gmt":"2021-03-17T11:33:35","slug":"deploy-di-servizi-su-aws-fargate-con-pipeline-di-continuous-delivery","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/deploy-di-servizi-su-aws-fargate-con-pipeline-di-continuous-delivery\/","title":{"rendered":"Deploy di servizi su AWS Fargate con pipeline di Continuous Delivery"},"content":{"rendered":"
Con l\u2019avvento di AWS Fargate<\/strong> la realizzazione di servizi basati su container assume finalmente tutto un altro senso. Infatti, prima del rilascio di Fargate l\u2019unico modo per usare Amazon ECS prevedeva il provisioning di un cluster di istanze EC2 gestite da Amazon (per software, aggiornamenti e configurazione). Con questo tipo di soluzione bisogna sostenere i costi dei cluster, progettare il sovradimensionamento per consentire lo scaling dei task, ed infine configurare e mantenere un valido sistema di autoscaling per non rimanere mai senza adeguate risorse per i container.<\/span><\/p>\n Con AWS Fargate tutto questo overhead di gestione pu\u00f2 essere lasciato ad AWS<\/strong>, che ci permette di avviare servizi basati su container pagandoli solo per il tempo effettivo di esecuzione. Non c\u2019\u00e8 quindi bisogno di preoccuparsi del cluster sottostante, ed \u00e8 possibile concentrarsi sullo sviluppo dei servizi.<\/span><\/p>\n Con AWS Fargate, AWS sta rendendo il container un oggetto di prim\u2019ordine nel panorama delle soluzioni di computing.<\/span><\/p>\n Automatizzare il deploy di servizi basati su container \u00e8 di fondamentale importanza per riuscire a sfruttare a pieno le potenzialit\u00e0 di AWS Fargate e del Cloud di AWS.<\/span><\/p>\n Ecco la nostra soluzione per implementare una pipeline di CD in grado di mettere in produzione ogni push sul ramo prescelto del repository.<\/span><\/p>\n I servizi chiave per l\u2019infrastruttura sono<\/span><\/p>\n Cominciamo con un breve glossario<\/span><\/p>\n Amazon Elastic Container Service (Amazon ECS)<\/b> \u00e8 un servizio di orchestrazione di container. Supporta Docker e consente di eseguire e ridimensionare facilmente le applicazioni<\/strong>. Con AWS Fargate \u00e8 possibile avviare ed orchestrare servizi basati su container sfruttando cluster completamenti gestiti da AWS e pagando per container.<\/span><\/p>\n Amazon Elastic Container Registry (ECR)<\/b> \u00e8 un registro di immagini Docker completamente gestito<\/strong> che semplifica agli sviluppatori la memorizzazione, la gestione e la distribuzione di immagini di container Docker. <\/span><\/p>\n Per smistare il traffico attraverso i container \u00e8 possibile sfruttare il servizio di Elastic Load Balancing. <\/span><\/p>\n AWS Elastic Load Balancing<\/b> instrada automaticamente il traffico in entrata delle applicazioni tra molteplici destinazioni, tra cui EC2, container, indirizzi IP e funzioni Lambda. <\/span><\/p>\n Elastic Load Balancing offre tre tipi di sistemi di bilanciamento del carico:<\/strong> <\/span><\/p>\n Il load balancer che ci sar\u00e0 utile per i servizi rilasciati su Fargate \u00e8 l\u2019Application Load Balancer (ALB)<\/strong><\/span><\/p>\n I sistemi Application Load Balancer sono indicati per il bilanciamento di traffico HTTP e HTTPS<\/strong>, e offrono instradamento avanzato delle richieste per la distribuzione di architetture moderne, ad esempio in microservizi e container. Questi sistemi operano a livello di richieste individuali (livello 7) e instradano il traffico in base al contenuto della richiesta.<\/span><\/p>\n Senza ulteriori indugi, passiamo ora al tutorial per la realizzazione di una pipeline di rilascio completamente automatizzata.<\/span><\/p>\n Durante il resto dell\u2019articolo daremo per scontato che tutto il codice del progetto si trovi su un repository compatibile con CodePipeline. <\/strong><\/span><\/p>\n La prima cosa da fare \u00e8 preparare un\u2019immagine del nostro servizio per poterla testare sia in locale che su AWS.<\/span><\/p>\n Occorre quindi aggiungere al progetto un Dockerfile<\/strong>, che andr\u00e0 successivamente pubblicato sul repository. All\u2019interno del file dovranno essere indicate le istruzioni per costruire un container che contenga tutto il software, le dipendenze, le librerie, le configurazioni ed il pacchetto con il nostro servizio.<\/span><\/p>\n Questo container pu\u00f2 essere tranquillamente testato in locale o in un ambiente controllato per verificarne il corretto funzionamento.<\/span><\/p>\n Una volta soddisfatti del risultato dei test locali, si pu\u00f2 procedere alla creazione di un\u2019immagine e alla pubblicazione della stessa su Amazon ECR.<\/span><\/p>\n Provvediamo quindi alla creazione di un repository ECR<\/strong>: l\u2019unico dato necessario alla creazione \u00e8 un nome valido.<\/span> Il nostro servizio avr\u00e0 bisogno di un<\/span> Load Balancer<\/b> per instradare il traffico tra i container replica.<\/span><\/p>\n Per questa ragione dobbiamo creare un Application Load Balancer<\/strong>, la cui configurazione pu\u00f2 essere lasciata in bianco. Non sar\u00e0 necessario definire dettagli di comportamento dell\u2019ALB perch\u00e8 sar\u00e0 ECS a gestirlo in modo dinamico durante le operazioni di scaling dei container.<\/span><\/p>\n Per quanto riguarda ECS, la prima cosa da fare \u00e8 creare un cluster. I cluster<\/strong> non sono altro che oggetti utilizzati per raggruppare a livello logico i servizi.<\/span><\/p>\n Per creare un cluster accediamo alla dashboard di ECS e selezioniamo \u201ccreate cluster\u201d.<\/span><\/p>\n Dal wizard scegliamo \u201cNetworking only\u201d, configurazione che indica ad AWS di utilizzare AWS Fargate per questo cluster virtuale.<\/span><\/p>\n Nel secondo ed ultimo step del wizard basta indicare il nome e se si desidera creare una nuova VPC, se si sceglie di non creare nessuna VPC \u00e8 possibile usare una di quelle gi\u00e0 configurate sul proprio account.<\/span><\/p>\n Il secondo passaggio \u00e8 creare una task definition.<\/strong> Questo oggetto raccoglie informazioni sul task come ad esempio nome, descrizione, IAM roles per deploy ed esecuzione, la dimensione del task in termini di RAM e CPU, e le specifiche del container che lo ospiter\u00e0.<\/span><\/p>\n Per la parte di configurazione del container occorre selezionare l\u2019immagine docker precedentemente salvata su ECR.<\/span><\/p>\n Per creare una task definition basta selezionare \u201cCreate task definition\u201d dall\u2019apposita schermata dall\u2019area di ECS. <\/span><\/p>\n Il passaggio essenziale \u00e8 scegliere AWS Fargate al primo step del wizard; completiamo poi con i dati richiesti seguendo le istruzioni e fornendo dimensionamento adeguato per il proprio task.<\/span><\/p>\n L\u2019ultimo oggetto da configurare si chiama servizio (Service).<\/strong><\/p>\n Un servizio \u00e8 definito da un task e da una terna di parametri che specificano quante istanze del task sono necessarie come minimo, valore attuale e massimo per permettere il corretto funzionamento del servizio.<\/span><\/p>\n Si faccia attenzione alla scelta della VPC, delle subnet e del load balancer creato precedentemente.<\/span><\/p>\n Alla fine della configurazione, puntando il browser all\u2019URL dell’ALB si dovrebbe visualizzare il proprio servizio.<\/span><\/p>\n Una volta configurato manualmente tutto l\u2019ambiente, \u00e8 possibile creare e configurare una pipeline per effettuare il deploy automatico ad ogni cambiamento del codice.<\/strong><\/span><\/p>\n Prima di iniziare la configurazione della pipeline occorrer\u00e0 aggiungere un file chiamato buildspec.yml<\/strong> nella root del repository. Lo scopo del file \u00e8 quello di contenere le istruzioni per effettuare il build di una nuova immagine del nostro servizio.<\/span><\/p>\n Dobbiamo infatti automatizzare il processo che abbiamo eseguito a mano nella parte iniziale dell\u2019articolo, ovvero la costruzione dell\u2019immagine docker a partire dal dockerfile e dal codice, il suo caricamento su ECR ed infine l\u2019aggiornamento di ECS per effettuare il deploy del servizio usando la nuova immagine.<\/span><\/p>\n Ecco una versione di esempio del file da aggiungere (buildspec.yml)<\/span><\/p>\n In rosso le parti da editare con i nomi specifici del proprio progetto.<\/span><\/em><\/p>\n CodePipeline \u00e8 il servizio di AWS che ci permetter\u00e0 di realizzare l\u2019automazione profondendo bassissimo effort di gestione e configurazione. Per eseguire le operazioni di build dell\u2019immagine invece, ci affideremo a CodeBuild, che andr\u00e0 ad eseguire il file con le istruzioni (buildspec.yml).<\/span><\/p>\n Cominciamo quindi con la configurazione della pipeline<\/strong> creandone una nuova su CodePipeline:<\/span><\/p>\n A questo punto, la pipeline prover\u00e0 ad andare in esecuzione in automatico, fallendo.<\/em><\/span><\/p>\n Si tratta di un fallimento atteso:<\/strong> la ragione risiede nel fatto che che il Wizard ha creato per noi un ruolo per CodeBuild, che per\u00f2 non ha tutti i permessi necessari per eseguire il push dell\u2019immagine su ECR.<\/span><\/p>\n Per porre rimedio occorre identificare il ruolo generato – il cui nome segue la seguente convenzione: code-build-<\/span>build-project-name<\/span>-service-role – e aggiungervi i seguenti permessi:<\/span><\/p>\n AmazonEC2ContainerRegistryPowerUser<\/b> per vedere funzionare la pipeline.<\/span><\/p>\n Se tutto ha funzionato come previsto, la pipeline sar\u00e0 ora funzionante e, ad ogni commit sul ramo prescelto, il servizio sar\u00e0 automaticamente aggiornato.<\/span><\/p>\n Con i container sempre pi\u00f9 al centro della scena DevOps \u00e8 importante conoscere gli strumenti a disposizione per effettuare scelte di progetto ponderate ed efficaci. Speriamo di esservi stati utili in questo senso \ud83d\ude09<\/span><\/p>\n Condividete con noi i vostri risultati, le vostre osservazioni, i vostri dubbi, i vostri spunti\u2026 il nostro team non vede l\u2019ora di approfondire il topic con voi!<\/span><\/p>\n [ATTENZIONE, SPOILER!]: se siete incuriositi da questo argomento, continuate a seguirci: in arrivo per voi un modo creativo per ottenere una pipeline automatica, altamente personalizzata, che utilizza i container come mezzo di automazione.<\/strong><\/span><\/p>\n Stay tuned!<\/span><\/p>\n #Proud2beCloud<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":" In questo articolo spieghiamo come abbiamo realizzato una pipeline di CD in grado di produrre una docker image ed effettuare […]<\/p>\n","protected":false},"author":8,"featured_media":409,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[241],"tags":[291,361,285,259,364,360],"class_list":["post-391","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-aws-codebuild","tag-aws-codecommit","tag-aws-codepipeline","tag-aws-fargate","tag-ci-cd","tag-continuous-delivery"],"yoast_head":"\n\n
\n
Parte 1: Preparazione della prima docker image<\/span><\/h2>\n
\n<\/span>Successivamente basta seguire le istruzioni di login e push per caricare la nostra immagine docker su ECR.<\/span><\/p>\n$(aws ecr get-login --no-include-email --region <regione>)<\/span>\r\ndocker build -t <nome immagine> .<\/span>\r\ndocker tag <nome immagine>:latest <ecr url>:latest<\/span>\r\ndocker push <ecr url>:latest<\/span><\/pre>\n
Parte 2: Configurazione di ECS Fargate e del Networking<\/span><\/h2>\n
<\/p>\n
<\/p>\n
<\/p>\n
La procedura di creazione \u00e8 analoga a quella degli altri oggetti configurati.<\/span><\/p>\n
<\/p>\n
<\/p>\n
<\/p>\n
<\/p>\n
Parte 3: Automatizzare il deploy<\/span><\/h2>\n
version: 0.2<\/span>\r\n\r\nphases:<\/span>\r\n \u00a0pre_build:<\/span>\r\n \u00a0\u00a0\u00a0commands:<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- echo Logging in to Amazon ECR...<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- aws --version<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- REPOSITORY_URI=<\/span><URL DELL\u2019IMMAGINE SU ECR><\/span><\/i><\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- IMAGE_TAG=${COMMIT_HASH:=latest}<\/span>\r\n \u00a0build:<\/span>\r\n \u00a0\u00a0\u00a0commands:<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- echo Build started on `date`<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- echo Building the Docker image... \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- docker build -t $REPOSITORY_URI:latest .<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG<\/span>\r\n \u00a0post_build:<\/span>\r\n \u00a0\u00a0\u00a0commands:<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- echo Build completed on `date`<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- echo Pushing the Docker images...<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- docker push $REPOSITORY_URI:latest<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- docker push $REPOSITORY_URI:$IMAGE_TAG<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- echo Writing image definitions file...<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0- printf '[{\"name\":\"<\/span><container name usato in task definition><\/span><\/i><\/span>\",\"imageUri\":\"%s\"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json<\/span>\r\nartifacts:<\/span>\r\n \u00a0\u00a0\u00a0files: imagedefinitions.json\r\n<\/span><\/pre>\n
\n
\n<\/span>Come sistema operativo bisogna scegliere <\/span>Ubuntu<\/b>, e come Runtime <\/span>Docker.<\/b><\/li>\n