Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

39
Universit ` a degli Studi di Trieste Dipartimento di Ingegneria e Architettura Corso di Studi in Ingegneria Informatica Tesi di Laurea Triennale Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps Laureando: Mattia Milleri Relatore: prof. Francesco Fabris Correlatore: ing. Sergio Benedetti ANNO ACCADEMICO 2015–2016

Transcript of Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Page 1: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Universita degli Studi di Trieste

Dipartimento di Ingegneria e Architettura

Corso di Studi in Ingegneria Informatica

Tesi di Laurea Triennale

Progetto e implementazione di una pipeline di

sviluppo software con tecnologie DevOps

Laureando:Mattia Milleri

Relatore:prof. Francesco Fabris

Correlatore:ing. Sergio Benedetti

ANNO ACCADEMICO 2015–2016

Page 2: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Indice

Introduzione 3

1 Strumenti DevOps 51.1 Vagrant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2 Confronto sistemi provisioning . . . . . . . . . . . . . . . . . 6

1.2.1 Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . 61.2.2 Chef . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2.3 Puppet . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2.4 Tabella di confronto sistemi provisioning . . . . . . . . 8

1.3 Jenkins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2 Pipeline di sviluppo 112.1 Applicazione . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.2 Configurazione Jenkins . . . . . . . . . . . . . . . . . . . . . . 122.3 Architettura del sistema . . . . . . . . . . . . . . . . . . . . . 132.4 Stage 1 - Build Tests . . . . . . . . . . . . . . . . . . . . . . . 14

2.4.1 Configurazione Vagrant . . . . . . . . . . . . . . . . . 152.4.2 Script Ansible . . . . . . . . . . . . . . . . . . . . . . . 16

2.5 Stage 2 - Stress Tests . . . . . . . . . . . . . . . . . . . . . . . 162.5.1 Configurazione Vagrant . . . . . . . . . . . . . . . . . 162.5.2 Script Ansible . . . . . . . . . . . . . . . . . . . . . . . 172.5.3 Test con JMeter e Selenium . . . . . . . . . . . . . . . 17

2.6 Stage 3 - Deploy su Google Cloud . . . . . . . . . . . . . . . . 182.6.1 Configurazione Google Cloud . . . . . . . . . . . . . . 192.6.2 Configurazione Vagrant . . . . . . . . . . . . . . . . . 192.6.3 Script Ansible . . . . . . . . . . . . . . . . . . . . . . . 20

Conclusioni 22

Codice sorgente 23Jenkinsfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23Vagrantfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26Ansible - playbook-stage1.yml . . . . . . . . . . . . . . . . . . . . . 29Ansible - playbook-stage2.yml . . . . . . . . . . . . . . . . . . . . . 31

1

Page 3: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Ansible - playbook-stage3.yml . . . . . . . . . . . . . . . . . . . . . 34

2

Page 4: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Introduzione

Il lavoro di tesi formalizzato in questo documento e stato eseguito pressoEsteco SPA. L’ambito e quello dello sviluppo di applicazioni in ambienteweb.

Lo scopo del lavoro e quello di automatizzare completamente tutta lapipeline di sviluppo di una applicazione web, a partire dalla compilazione efino alla messa in produzione, utilizzando degli strumenti DevOps.

Cos’e una pipeline di sviluppo?

Una pipeline di sviluppo e la rappresentazione di tutti i passi del percorsocui un software e assoggettato prima di poter arrivare in produzione.

Per ovvii motivi si ha l’esigenza di automatizzare tutto il percorso; ciorisponde alle seguenti richieste, necessarie per avere un’applicazione stabilee sicura:

• se devono esserci dei fallimenti in un qualche punto della pipeline,e importante avere dei test che falliscono presto, in modo da poterreagire tempestivamente agli errori, nei vari test di validazione, distress e di usabilita;

• togliere la componente di errore umano nella fase di installazione. Te-st, configurazioni e installazioni vengono eseguite sempre esattamentenello stesso modo;

• avere la certezza dell’uguaglianza fra le varie macchine di test e diproduzione. Essendo create in modo automatico a partire da unoscript esse saranno sempre identiche;

• rendere la preparazione dell’ambiente e l’installazione dell’applicazionequalcosa di ”programmabile”; in questo modo, una volta creato loscript, tutti possono eseguirlo, non e piu necessario fare affidamentosu una singola persona che era l’unica a conoscere come procedere conl’installazione.

3

Page 5: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Cosa si intende con strumenti DevOps?

DevOps e un termine coniato nel 2009 da Patrick Debois; esso descrive uninsieme di pratiche volte ad aiutare la collaborazione fra quelli che sono idue maggiori agenti nel processo di sviluppo di una applicazione: gli svilup-patori (DEVelopers) da una parte e la parte di amministrazione di sistemi(OPerationS) dall’altra.

Il risultato di tale approccio e una forte automazione del processo pro-duttivo, che permette di velocizzare e rendere piu affidabile la messa inproduzione di un’applicazione.

Con strumenti DevOps indichiamo quindi tutte quelle applicazioni chepermettono di automatizzare le operazioni di amministrazione di sistema.

Nei prossimi capitoli esamineremo nel dettaglio la struttura della pipelinee il funzionamento degli strumenti necessari per realizzarla.

4

Page 6: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Capitolo 1

Strumenti DevOps

In questo capitolo descriveremo brevemente il funzionamento degli strumentidi automazione DevOps che andremo ad utilizzare in seguito all’interno dellapipeline.

1.1 Vagrant

Vagrant e un programma creato nel 2010 da Mitchell Hashimoto e permettela creazione e manutenzione di macchine virtuali.

La costruzione di una macchina virtuale e interamente formalizzata al-l’interno di uno script, detto Vagrantfile, che permette di descrivere le ca-ratteristiche richieste all’interno di quest’ultima.

Vagrant e caratterizzato da 3 componenti principali, che entrano in giocoin successione nella creazione della macchina virtuale.

Il primo sono le Vagrant Box.

Ogni macchina virtuale viene generata a partire da una certa immagi-ne, detta Vagrant Box, che costituisce la base con il sistema operativoche andremo ad utilizzare come fondamenta nella costruzione.

Esistono varie Box pronte all’uso che possono essere scaricare diretta-mente dal sito di Vagrant. Solitamente queste sono create e messe adisposizione da altri utenti o direttamente dal produttore del sistemaoperativo, a meno che non richiedano licenze particolari a pagamento,come nel caso di Windows o MacOS.

Alternativamente, se dovessero esserci esigenze o prerequisiti partico-lari, e sempre possibile creare una Box a partire da macchina virtualepreesistente.

Il secondo sono i Providers.

5

Page 7: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Il Provider e il sistema utilizzato nella creazione della macchina vir-tuale. Quello di default e VirtualBox, ma tramite un sistema di plugine possibile ottenere il supporto per altri provider, come ad esempioVMware, Google Cloud o Amazon AWS.

Il terzo sono i Provisioners.

I Provisioners sono gli strumenti che si occupano di configurare auto-maticamente la macchina in un certo modo una volta creata.

Oltre alla possibilita di fornire direttamente comandi di shell, esiste ilsupporto anche a strumenti piu avanzati, fra i quali cito Ansible, Chefe Puppet che esamineremo in seguito.

1.2 Confronto sistemi provisioning

In questa sezione descriveremo tre diversi sistemi di provisioning: Ansible,Chef e Puppet.

Confronteremo fra loro le diverse caratteristiche di ognuno, decidendoinfine qual e tra questi lo strumento migliore, cioe quello che si adatta meglioai requisiti del nostro progetto.

1.2.1 Ansible

Ansible e un sistema di automazione open-source che permette il provisio-ning e la configurazione remota di macchine virtuali oltre all’installazione diapplicazioni web.

Come la maggior parte dei sistemi di provisioning, Ansible riconosce unaarchitettura a due livelli, composta da una macchina di controllo e dai nodi.

La caratteristica principale di Ansible e la sua architettura agentless, chenon richiede installazione di client sui nodi da gestire.

Il funzionamento e determinato da un Inventory, che contiene tutte leinformazioni riguardo ai nodi da gestire piu tutte le operazioni da eseguiresu ogni singolo nodo.

Il Playbook che contiene le operazioni da eseguire sui nodi non e unvero e proprio script, e invece la descrizione di uno ”stato” che la macchinadeve avere. In base allo stato attuale della macchina verranno decretatequali fra le tante operazioni descritte vanno eseguite per raggiungere lo statodesiderato, e di conseguenza, i moduli relativi alle operazioni che verrannoinviati ed eseguiti sui vari nodi.

La comunicazione fra i il nodo di controllo e quello da controllare avvienetramite il protocollo SSH: una volta avvenuta la connessione il server dicontrollo invia dei moduli all’altro che vengono successivamente eseguiti.

6

Page 8: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

1.2.2 Chef

Chef e uno strumento open-source di gestione della configurazione e provi-sioning.

Utilizza una architettura a 3 strati composta da:

Chef DK Il Chef Development Kit va installato su una workstation chesara utilizzata per la creazione dei vari script di configurazione edinstallazione da eseguire sui nodi.

Chef Server Agisce come server di controllo e contiene sia tutte le informa-zioni relative ai nodi da controllare che i ”Cookbook” con le operazionida eseguire sui singoli nodi.

Chef Client Deve essere in esecuzione su ogni nodo controllato, esegue unpolling periodico sul server di controllo, se trova delle differenze lescarica e aggiorna il nodo allo stato definito dai Cookbook.

Alternativamente alla modalita client / server, puo essere anche eseguitoin modalita standalone ”chef-solo” direttamente sul nodo da controllare.

La comunicazione fra il server e il client e regolata da un protocolloproprietario. Viene utilizzata una coppia di chiavi RSA per l’autenticazione,questo previene che un nodo possa accedere a dati che non lo pertengono eassicura che vengano gestiti solo i nodi registrati.

1.2.3 Puppet

Puppet e uno strumento open-source per la gestione della configurazione delsoftware.

Sfrutta un linguaggio dichiarativo proprietario per la descrizione dellaconfigurazione dei nodi.

Utilizza una struttura client / server, composta da:

Puppet Master e il server con tutte le istruzioni, detti ”Manifests”, perla configurazione dei nodi.

Puppet Agent e il client da installare su ogni nodo, si collega al server,recupera le configurazioni e le installa, comunicando il risultato alserver.

Puppet DB e una parte opzionale della struttura che affianca il server esalva molte informazioni aggiuntive riguardo ai nodi e all’esecuzionedi ogni operazione.

La comunicazione fra client e server avviene tramite Facter. Facter euna libreria di profiling che comunica via protocollo HTTPS con il server,fornendogli informazioni relative al client come sistema operativo, IP e confi-gurazione attuale. Il server quindi risponde con la configurazione desiderata

7

Page 9: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

e fornisce i comandi specifici che l’agente del client dovra eseguire in base alsistema operativo presente sul nodo.

Essendo la comunicazione basata su HTTPS sara necessario configuraredei certificati SSL, sia per il server che per il client, per autorizzare lo scambiodi informazioni fra le varie parti.

1.2.4 Tabella di confronto sistemi provisioning

In questa tabella confronteremo i tre sistemi di provisioning appena descrittiin base alle caratteristiche ritenute piu importanti in riferimento al nostroprogetto.

ANSIBLE CHEF PUPPETIn questi test tutti e 3 i sistemi di provisioning sono utilizzatia partire da una virtual machine Ubuntu 16.04 LTS “XenialXerus” 64 bit creata con Vagrant.

Community La community e molto nutrita in tutti e tre i casi. Que-sto garantisce che esistera un certo livello di supporto per iplugin in futuro.

Ansible Galaxy ChefSupermarket

Puppet Forge

Numero”ricette”presenti

9713 3163 4716Esistono molti duplicati per ogni singola ricetta, perche ma-gari lo stesso modulo viene creato da molti autori diver-si o con minime variazioni per risolvere problemi specifici.Un maggior numero di ricette non e quindi necessariamenteindice di maggior qualita delle ricette stesse o di maggiorcopertura software.Il numero di ricette per Windows o MacOS e notevolmenteinferiore al numero di ricette per Linux.

Linguaggio Open source,Python

Open source,Ruby

Open source,Ruby

Linguaggiodi configu-razione escripting

Playbook scritti inYAML (HumanReadable)

Recipes e Coo-kbooks scritti inRuby, ma non c’enecessita di cono-scere il linguaggioper crearne uno

Manifests scrittiin Puppet langua-ge

Architettura Agentless Client / Server +Workstation conChefDK per lacreazione delle ri-cette

Client / Server

8

Page 10: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Modo difunziona-mento

Task eseguiti se-quenzialmente, seuno fallisce inter-rompe l’esecuzio-ne.

Task eseguiti se-quenzialmente, seuno fallisce inter-rompe l’esecuzio-ne. Cerca di falli-re il prima possi-bile tramite anali-si dello script (es.file che manca-no. . . ).

Task eseguiti inordine casuale,ma supportal’impostazione diun ordine precisodi esecuzione.Esegue ogni vol-ta tutti i taske segnala quantifalliscono o no.

Toolaggiuntivi

I moduli esterninecessari per l’e-secuzione vengo-no installati sullaworkstation dovesi esegue Ansible

I moduli ester-ni vanno instal-lati con ChefDKe vengono salvatinel cookbook chedovra essere mes-so sul server

Bisogna installarei moduli necessa-ri tramite coman-do sulla macchi-na ospite (e possi-bile installarli au-tomaticamente inbase al Manifest,ma cioo richiedestrumenti di ge-stione addiziona-li)

Velocita diprovisio-ning eupdate

Dai test eseguiti la velocita e essenzialmente la stessa contutti e 3 i sistemi. In quanto il tempo di installazione e det-tato piu dal tempo di scaricamento dei pacchetti da installa-re che dal tempo necessario all’esecuzione di un particolareprovisioner.

Supportoalla cloud

La creazione delle macchine virtuali e fornita da Vagrant chesupporta di base VirtualBox, Hyper-V e Docker.Il supporto per la cloud, come ad esempio Amazon AWS oGoogle Cloud, e fornita tramite plugin.

Alla fine del confronto, in base a quelle che sono le esigenze del nostroprogetto, e stato deciso di utilizzare Ansible.

La scelta e stata dettata da:

• semplicita di architettura: il sistema prevede solo una macchina ser-ver che va ad eseguire degli script su determinate macchine, non enecessario organizzare e configurare nessun client;

• linguaggio di scripting : sfruttando YAML, ovvero un linguaggio ”hu-man readable”, risulta molto piu chiaro e comprensibile rispetto aglialtri;

9

Page 11: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

• minor impatto sulla macchina ospite: sfruttando una architetturaagentless non necessita di installazioni di client sulle varie macchineospite, eliminando quindi sia problemi di aggiornamento e manuten-zione degli stessi, che di contaminazione dell’ambiente di esecuzione;

• praticita di installazione dei plugin: e sufficiente installarli soltantosulla macchina server;

• piu adatto per le esigenze del nostro progetto: la creazione di macchinevirtuali ad-hoc per il testing era piu in sintonia con il funzionamentodi Ansible, in quanto esso prevede che sia il server quello che va adapplicare le modifiche sui nodi, al contrario, le altre due alternativeprevedono un sistema in cui sono i singoli nodi quelli che vanno aprendere le configurazioni dal server centrale.

Tutti questi elementi gli conferiscono una maggiore semplicita e lo ren-dono quello piu adatto all’utilizzo, relativamente al nostro caso d’uso.

1.3 Jenkins

Jenkins e un server di Continuous Integration open-source scritto in lin-guaggio Java.

Permette di definire e automatizzare il processo di costruzione e installa-zione di un’applicazione, descrivendo in una pipeline tutti i passi, di cui so-litamente i piu importanti sono: compilazione, test e installazione, necessariper il deployment di un’applicazione web in produzione.

Viene eseguito come servizio sulla macchina che lo ospita, configurazionee funzionamento sono completamente gestiti tramite interfaccia web. Questopermette l’installazione alternativamente su una macchina remota, quasiessenziale nel caso in cui il progetto software sia sviluppato da un team diprogrammatori, con necessita di accesso simultaneo per controllare svariateparti del processo.

La struttura di Jenkins supporta dei plugin che permettono l’amplia-mento delle funzionalita della piattaforma di base. Funzionalita aggiuntivepossono essere, ad esempio, l’interfacciamento con vari sistemi di gestionedel codice sorgente o l’implementazione di diversi strumenti per il testing,fornendo una pratica interfaccia visuale per l’analisi dei risultati.

Questo strumento sara il nocciolo attorno al quale andremo a costruirela pipeline di sviluppo software, fornendo la base di automazione da cuieseguire tutti gli altri strumenti necessari.

10

Page 12: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Capitolo 2

Pipeline di sviluppo

Lo scopo del lavoro di tesi e quello di progettare una pipeline completa disviluppo software.

La pipeline prevede, oltre alla compilazione del codice, anche l’esecuzionedi vari test che andranno eseguiti su delle macchine virtuali dove sara statainstallata l’applicazione.

La pipeline sara divisa in 3 principali sezioni o ”stage”:

Stage 1 Compilazione dell’applicazione, test di unita e di integrazione.

Stage 2 Test di carico e di interfaccia utente.

Stage 3 Messa in produzione su Google Cloud.

Introdurremo ora l’applicazione che andremo ad utilizzare. Esamineremopoi le configurazioni necessarie e le operazioni eseguite per ogni stage dellapipeline.

2.1 Applicazione

Si e scelto di utilizzare Shopizer come applicazione di test per cui costruirela pipeline di sviluppo.

Shopizer e una applicazione open-source scritta in linguaggio Java chepermette la creazione di siti web volti alla vendita di prodotti.

Supporta due diversi tipi di DBMS: H2 e MySQL, che, date le loro diver-se caratteristiche, useremo separatamente nei primi due stage per eseguiredifferenti batterie di test.

Elenchiamo ora i prerequisiti dell’applicazione, questi andranno soddi-sfatti dai vari strumenti che useremo in seguito:

• lo strumento di build automation Maven, utilizzato sia per la compi-lazione, che per l’esecuzione dei test di unita e integrazione

11

Page 13: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Figura 2.1: Schermata Home di un sito creato con Shopizer

• un sistema operativo su cui far girare la macchina virtuale Java e l’ap-plication server: non viene richiesto niente di particolare, utilizzeremoun sistema operativo Linux Ubuntu 16.04 LTS “Xenial Xerus” a 64bit

• installazione di Java 8, di cui utilizzeremo la versione open source

• un application server: utilizzeremo Apache Tomcat 8

• un server MySQL

2.2 Configurazione Jenkins

Jenkins necessita di una configurazione alquanto limitata, in quanto, nono-stante sia il motore che muovera il processo produttivo, recuperera tutte leinformazioni relative alle operazioni da eseguire da un file di script salvatonel sistema di gestione sorgenti del progetto.

Le operazioni da eseguire sono:

• la creazione di uno o piu utenti che possano accedere al sistema.

• L’installazione di tutti i plugin necessari al funzionamento della pipe-line, nel nostro caso essi sono:

12

Page 14: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Plugin Pipeline essenziale, permette la creazione del percorso disviluppo software

Plugin Git necessario per recuperare il codice sorgente dell’applica-zione dalla repository

Plugin JUnit necessario per la pubblicazione dei risultati dei varitest eseguiti con Maven

• La creazione di un progetto di tipo Pipeline.

• Configurare il progetto creato nel passo precedente in modo che possaprendersi lo script, detto Jenkinsfile, con le operazioni da eseguire nellaPipeline. Questo e fatto semplicemente fornendo l’url della repositoryGit del nostro progetto.

• Assicurarsi che la coppia di chiavi RSA sia presente nella cartella .ssh/

dell’utente jenkins e copia della chiave privata di autenticazione aGoogle Cloud nella cartella del progetto.

Da questo momento e sufficiente premere il tasto Build per eseguireautomaticamente tutti i passi descritti nel Jenkinsfile.

Se si dovesse verificare un errore in uno qualsiasi del vari passaggi, ver-rebbe interrotta l’esecuzione dei passi successivi e l’intera Pipeline verrebbesegnalata come “fallita”.

2.3 Architettura del sistema

Il sistema sara strutturato nel modo seguente: avremo una macchina prin-cipale, che puo essere la nostra workstation o anche una macchina remota,dove sara installato Jenkins. Vista la mole di lavoro richiesta: compilazionedi sorgenti e creazione di macchine virtuali, e importante che sia fornita diun hardware abbastanza potente.

Tutto il codice sorgente, sia relativo all’applicazione che ai vari file discript e configurazione necessari nel processo di sviluppo sono tutti versio-nati in una repository Git ospitata in locale sulla stessa macchina. Cionono-stante, alcuni file, come ad esempio chiavi private RSA o file contenenti datisensibili, non possono essere salvati in sistemi di versionamento per motividi sicurezza e verranno quindi installati a mano.

Tutte le operazioni della pipeline verranno eseguite dall’utente jenkins apartire dalla cartella nel workspace relativa al nostro progetto. E importantequindi assicurarsi che tutti i file necessari e i permessi sugli stessi sianoimpostati correttamente,

Va fatta una distinzione importante: le operazioni che vedremo descritteall’interno del Jenkinsfile di configurazione della pipeline saranno eseguite

13

Page 15: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

in locale sulla macchina principale, tutti gli script Ansible invece verrannoeseguiti sulle macchine virtuali create a richiesta.

In generale avremo quindi Jenkins che eseguira in locale i comandi sullasua pipeline, usando Vagrant per la creazione delle virtual machines che asua volta richiamera gli script di Ansible per effettuare il provisioning.

2.4 Stage 1 - Build Tests

In questa prima fase verra effettuata la compilazione del codice con supportoal DBMS H2, questo e un DBMS residente in memoria e non ha bisogno dinessuna configurazione per funzionare, fornisce di conseguenza un ambientepiu semplice dove effettuare i primi test.

Figura 2.2: Passi del primo stage della pipeline

A cui corrisponde la seguente sezione di codice all’interno del Jenkinsfile,il codice completo e disponibile in appendice a pagina 23:

stage(’Clone Repository’) {

git ’${repository_url}’

}

stage(’Build’) {

sh ’mvn clean install -DskipTests’

}

stage(’Create Virtual Machine - Stage1’) {

14

Page 16: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

sh ’vagrant up stage1’

}

La prima operazione fondamentale da eseguire e la clonazione dellarepository con il codice sorgente.

In seguito il codice viene compilato. Vengono saltati i test in questaprima fase in quanto necessitano della macchina virtuale funzionanente perpoter essere eseguiti con successo.

Viene quindi creata e configurata completamente la macchina virtuale.

stage(’Tests - Stage1’) {

try {

sh ’mvn test’

} finally {

junit ’sm-shop/target/surefire-reports/*.xml’

}

}

Ora che la macchina virtuale con l’applicazione e funzionante, in que-st’ultima sezione vengono effettuati i test e, indipendentemente dal successoo fallimento della loro esecuzione, pubblicati i risultati.

2.4.1 Configurazione Vagrant

Essendo questa la prima volta che lo incontriamo, descriviamo la configura-zione di Vagrant. La configurazione sara molto simile per quanto riguardale prime due macchine virtuali che andremo a creare.

Con riferimento al codice completo in appendice a pagina 26.Come prima cosa viene impostato il tipo di immagine da utilizzare per

la creazione della macchina:

config.vm.box = "ubuntu/xenial64"

nel nostro caso un linux Ubuntu 16.04 LTS “Xenial Xerus”.In seguito viene eseguito il provisioning sulla macchina con Ansible. No-

tiamo come viene installato, tramite comandi di shell di sistema, il linguaggioPython, necessario al funzionamento di Ansible sulla macchina ospite.

stage1.vm.provision "shell", inline: <<-SHELL

sudo apt-get update

sudo apt-get install -y python

SHELL

In questa sezione viene richiamato per l’esecuzione lo script con la confi-gurazione desiderata della macchina virtuale. Il fatto che venga eseguito co-me sudo indica che avra poteri di amministratore all’interno della macchina,necessari per l’installazione dei vari programmi.

15

Page 17: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

stage1.vm.provision "ansible" do |ansible|

ansible.playbook = "playbook-stage1.yml"

ansible.sudo = true

end

2.4.2 Script Ansible

Con riferimento al codice completo in appendice a pagina 29.In questo primo caso lo script e molto semplice.Ci si assicura che l’application server Tomcat 8 sia installato e funzio-

nante.Vengono impostate alcune opzioni di Java, in quanto l’applicazione che

stiamo usando necessita di una quantita di memoria superiore a quella cheviene designata di default.

L’ultimo passaggio e quello di installazione dell’applicazione, per effet-tuarla e sufficiente copiare il file sm-shop.war generato nella precedente fasedi compilazione e copiarlo nella cartella webapps/ di Tomcat.

2.5 Stage 2 - Stress Tests

In questa fase ricompileremo l’applicazione con il supporto per MySQL ein seguito installeremo una macchina virtuale su cui effettuare dei test dicarico tramite JMeter e di usabilita con Selenium.

Figura 2.3: Passi del secondo stage della pipeline

2.5.1 Configurazione Vagrant

Sempre in riferimento al codice del Vagrantfile di prima a pagina 26.Notiamo che il codice per il secondo stage e praticamente lo stesso, la

differenza piu importante e data dalla riga:

stage2.vm.network "private_network", ip: "192.168.1.3"

16

Page 18: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

in cui viene configurata una rete virtuale fra la macchina principale e quellavirtuale, questo passo e necessario per permettere l’accesso diretto al da-tabase da parte di JMeter, in modo da potergli permettere di effettuare itest.

2.5.2 Script Ansible

In riferimento al codice del playbook per Ansible relativo allo Stage 2 inappendice a pagina 31.

In questo caso notiamo che lo script e piu complicato rispetto al passato.

Oltre all’installazione e configurazione di Tomcat come nello stage pre-cedente troviamo molte altre operazioni.

Viene installato il server MySQL insieme ai prerequisiti per permetteread Ansible di controllarlo.

Vengono creati il database e l’utente che verra utilizzato dall’applicazioneper accederci.

E importante notare che il database viene creato fornendogli uno scriptSQL, il cui scopo e: aumentare il numero di prodotti con cui viene popolatoinizialmente e impostare tutte le informazioni necessarie per configurare ipagamenti e le spedizioni, fondamentali per riuscire a completare un ordine.

2.5.3 Test con JMeter e Selenium

In questa sezione introdurremo altri due strumenti, utilizzati per effettuaredei test di carico sulla nostra applicazione.

JMeter

JMeter e uno strumento che permette l’esecuzione di test di carico su unsito web.

I test sono composti da un certo elenco di pagine, JMeter procede adeffetturare una chiamata HTTP per ogni singola pagina dell’elenco.

Se si volessero eseguire dei test su un database, al posto dell’elenco dipagine da visitare, ci sarebbe un elenco di query SQL da eseguire.

In ognuno dei due casi sono necessarie altre tre informazioni:

• il numero di threads, cioe di utenti simulati, da eseguire in parallelo

• il periodo di rampa, che imposta quanto a lungo ritardare la parten-za dei singoli utenti, ad esempio se impongo un periodo di 10 secondi,JMeter finira di far partire tutti i miei utenti virtuali dopo 10 secondi

• il numero di ripetizioni da eseguire per ogni utente

17

Page 19: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Selenium

Selenium e un programma che permette di automatizzare la navigazione dipagine web.

Utilizza un plugin del browser web Firefox per creare i propri test,eseguibili singolarmente o in suite.

La creazione di un test e effettuata avviando la modalita di registrazio-ne la quale provvede a catturare le operazioni effettuate mentre si navigamanualmente sul sito.

In seguito l’esecuzione dei test e effettuata da un runner che, attraversodei driver, controllera i vari browser su cui lanciare i test automaticamente.

Nel nostro caso, l’utente jenkins non aveva le autorizzazioni necessarieper eseguire programmi sul server grafico X11. Abbiamo dovuto quindi uti-lizzare Xvfb per creare un ambiente grafico virtuale dove far partire Chrome,che e il browser con cui abbiamo effettuato i test.

Una volta eseguiti i test, sia con JMeter che con Selenium, viene richia-mato un plugin di Jenkins che permette di salvare e pubblicare nell’inter-faccia della pipeline i file con i risultati.

2.6 Stage 3 - Deploy su Google Cloud

In questa terza ed ultima fase descriveremo come e stato effettuato il deploydell’applicazione in un ambiente cloud.

Figura 2.4: Passi del terzo stage della pipeline

18

Page 20: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Per quanto sia il passo piu semplice dal punto di vista della pipeli-ne, richiede un certo numero di configurazioni da fare manualmente perla preparazione dell’ambiente di produzione su Cloud di Google.

2.6.1 Configurazione Google Cloud

Come gia anticipato in precedenza ci sono parecchie operazioni da effettuareper poter configurare correttamente l’accesso e la conseguente creazione egestione di macchine virtuali tramite Vagrant.

Le varie operazioni da compiere sono le seguenti:

• Eseguire l’accesso alla Google Developer Console con un utente Google.

• Creare un progetto.

• Nella sezione “Metadata”, importare le chiavi RSA pubbliche per laconnessione via SSH fra Vagrant e la virtual machine in cloud.

• Creare un account di servizio che verra utilizzato per eseguire tutte leoperazioni sulle macchine virtuali.

• Fornire all’account appena creato tutti i permessi necessari per poterfunzionare correttamente.

• Scaricare il file JSON con la chiave privata necessaria per autenticareautomaticamente l’account di servizio.

• Impostare correttamente le regole del firewall per permettere la con-nessione alla propria applicazione una volta installata. Di default tuttele connessioni remote alla macchina sono bloccate.

2.6.2 Configurazione Vagrant

La configurazione di Vagrant differisce notevolmente rispetto agli stage pre-cendenti. Ci riferiamo nuovamente al codice completo del Vagrantfile apagina 26.

Utilizzeremo un nuovo provider, google e non piu virtualbox e saranecessario inoltre cambiare l’immagine di base, la Vagrant Box, in quantoGoogle fornisce direttamente una lista di immagini gia pronte da utilizzare.

Vediamo le configurazioni nel dettaglio.Come prima cosa viene impostata la nuova immagine di base:

stage3.vm.box = "google/gce"

Inseriamo le informazioni con cui abbiamo configurato la Google Cloud :

google.google_project_id = ’#{project_id}’

google.google_client_email = ’#{service_account_mail}’

google.google_json_key_location = ’#{json_private_key}’

19

Page 21: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Descriviamo il tipo di macchina virtuale che desideriamo creare:

google.name = ’#{instance_name}’

google.zone = "europe-west1-d"

google.machine_type = "n1-standard-1"

google.image = "ubuntu-1604-xenial-v20170202"

Queste informazioni comprendono:

• il nome dell’istanza, cioe della virtual machine, da creare

• la zona dove creare l’istanza

• il tipo di macchina desiderata, scegliendo quindi numero di processorie memoria da installare

• l’immagine con il sistema operativo con cui creare la macchina

Ultima configurazione da fare e imporre lo stesso nome utente con cuiabbiamo creato le chiavi RSA che abbiamo importato in Google Cloud, oltread assicurarci che prenda il file giusto con le chiavi.

override.ssh.username = ’#{ssh_user_name}’

override.ssh.private_key_path = "~/.ssh/id_rsa"

Oltre a queste impostazioni il resto dello script rimane invariato rispettoagli stage precedenti.

2.6.3 Script Ansible

A causa della macchina di base leggermente diversa fra questo stage e quelliprecedenti, alcuni passaggi dello script Ansible hanno dovuto esser modificatileggermente rispetto a prima per essere eseguiti senza problemi.

Possiamo verificarlo confrontando i sorgenti in appendice alle pagine 31(Stage 2 ) e 34 (Stage 3 ).

Nonostante gli script di configurazione riportino alcune differenze fra diloro, il risultato finale dopo l’esecuzione e lo stesso in entrambi i casi.

20

Page 22: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Fig

ura

2.5

:R

app

rese

nta

zion

eco

mp

leta

del

lap

ipel

ine

inJen

kin

s

21

Page 23: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Conclusioni

Il progetto di creazione di una pipeline completa per l’automazione e av-venuto con successo, dimostrando che e possibile eliminare la necessita diesecuzione manuale di molte operazioni all’interno del processo di svilupposoftware.

Conseguenze di questo approccio automatizzato, oltre a quello di rispar-mio di tempo, sono di poter effettuare la messa in produzione di una appli-cazione in modo piu coerente, il che porta l’applicazione stessa ad essere piustabile e sicura.

Sviluppi futuri

Possibili sviluppi futuri includono l’implementazione di nuove tipologie ditest, come ad esempio test sulla sicurezza del sistema, per assicurarsi di nonesporre un sistema vulnerabile alla rete.

Un’altra tipologia di test da inserire sarebbe quella di test di accettazioneda parte dell’utente, che tramite l’interfaccia stessa di Jenkins potrebbeautonomamente creare la propria istanza dell’applicazione, eseguire i test suuna sessione browser aperta automaticamente e infine compilare un rapportosul test sempre rimanendo all’interno dell’interfaccia di Jenkins.

Fra gli sviluppi futuri possiamo anche includere la creazione di una repo-sitory aziendale di macchine virtuali per Vagrant, il che risponde alla neces-sita di avere macchine macchine di test configurate in modi molto particolari.Questo avviene soprattutto se consideriamo sistemi di test che necessitanodi sistemi operativi Windows o MacOS dove l’installazione e generalmentepoco automatizzabile e richiede l’inserimento delle licenze d’uso che sono apagamento.

In alternativa, fornendo gia macchine pronte all’uso, una repository lo-cale puo essere utilizzata soltanto per evitare di sprecare inutilmente deltempo scaricando e installando gli stessi pacchetti software ogni volta cheviene creata una nuova istanza per far girare i test.

22

Page 24: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Codice sorgente

Jenkinsfile

Questo e il codice sorgente della pipeline di sviluppo software creata conJenkins. Verra eseguito sulla workstation dove avremo installato Jenkins eprocedera a compilare l’applicazione e richiamare i comandi per la gestionedelle virtual machine.

#!groovy

node {

stage(’Clone Repository’) {

// Clones the git repository with the source code of our

// project

git ’${git_url}’

}

stage(’Build’) {

// Builds the application, but skips tests that will be run

// at a later stage in the pipeline

sh ’mvn clean install -DskipTests’

}

stage(’Create Virtual Machine - Stage1’) {

try {

// Destroy all existing virtual machines

sh ’vagrant destroy --force’

sh ’vagrant up stage1’

} catch (err) {

// Sends a email in case of an error during the creation

// of the first virtual machine

mail to: ’${user_mail}’,

subject: ’ERRORE’,

body: ’Si e verificato un errore ${err.message}’

}

}

stage(’Tests - Stage1’) {

23

Page 25: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

try {

// Runs the tests

sh ’mvn test’

} finally {

// Publishes the results using junit

junit ’sm-shop/target/surefire-reports/*.xml’

}

}

stage(’Modify sources and build with MySQL support.’) {

// Copies the file with the correct settings for building

// the application with MySQL support

sh ’cp database.properties \

sm-shop/src/main/resources/database.properties’

sh ’mvn clean install -DskipTests’

}

stage(’Create Virtual Machine - Stage2’) {

// Destroys out previous stage virtual machine and creates

// the second one, this time including MySQL server

sh ’vagrant destroy --force’

sh ’vagrant up stage2’

}

stage(’Tests - Stage2’) {

try {

sh ’mvn test’

} finally {

junit ’sm-shop/target/surefire-reports/*.xml’

}

}

stage(’Install JMeter’) {

// Downloads and installs JMeter to a local directory

if (fileExists(’apache-jmeter-3.1/’)) {

} else {

sh ’wget "${jmeter_url}"’

sh ’tar -xzf apache-jmeter-3.1.tgz’

}

// Downloads and installs MySQL JDBC connector for JMeter

if (fileExists(’${mysql_connector_name}’)) {

} else {

sh ’wget ${mysql_connector_url}’

sh ’tar -C apache-jmeter-3.1/lib/

--strip-components 1 \

-xzf ${mysql_connector_name}’

}

}

24

Page 26: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

stage(’Tests with JMeter’) {

// Needs this wait time for the Vm to get online.

sh ’sleep 2m’

// Load test webapp

sh ’./apache-jmeter-3.1/bin/jmeter -n

-t jmeter-test.jmx -l jmeter-test.jtl’

// Load test database

sh ’./apache-jmeter-3.1/bin/jmeter -n

-t jmeter-mysql.jmx -l jmeter-mysql.jtl’

// Publish test result

archiveArtifacts ’jmeter-test.jtl,

jmeter-mysql.jtl,

jmeter.log’

}

stage(’Install Selenium and chromedriver’) {

// Install selenium

if (fileExists(’${selenium_name}’)) {

} else {

sh ’wget ${selenium_url}’

}

// Install chromedriver

if (fileExists(’chromedriver’)) {

} else {

sh ’wget ${chromedriver_url}’

sh ’unzip ${chromedriver_name}’

}

}

stage(’Tests with Selenium’) {

// Run a script where we

// setup xvfb for headless chrome

// and run selenium tests

sh ’sh selenium-test.sh’

// Publish test result

archiveArtifacts ’selenium-results.htm’

}

stage(’Deploy on Google Cloud’) {

sh ’vagrant up stage3 --provider=google’

}

}

25

Page 27: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Vagrantfile

Questo e il codice sorgente di Vagrant utilizzato nella creazione delle virtualmachine.

# -*- mode: ruby -*-

# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure

# configures the configuration version (we support older styles for

# backwards compatibility). Please don’t change it unless you know what

# you’re doing.

Vagrant.configure("2") do |config|

# Every Vagrant development environment requires a box. You can

# search for boxes at https://atlas.hashicorp.com/search.

config.vm.box = "ubuntu/xenial64"

# Disable automatic box update checking. If you disable this, then

# boxes will only be checked for updates when the user runs

# ‘vagrant box outdated‘. This is not recommended.

# config.vm.box_check_update = false

config.vm.provider "virtualbox" do |vb|

# Customize the amount of memory on the VM:

vb.memory = "2048"

end

# Create virtual machine for Stage1 (H2 database)

config.vm.define "stage1" do |stage1|

# stage1.vm.network "private_network", ip: "192.168.1.2"

# We need this port forwarding to avoid conflicts, because the

# localhost is already hosting the Jenkins server on port 8080

stage1.vm.network "forwarded_port", guest: 8080, host: 8085

# We need to make sure to have python installed to allow Ansible

# to work

stage1.vm.provision "shell", inline: <<-SHELL

sudo apt-get update

sudo apt-get install -y python

SHELL

# This calls the Ansible script for provisioning

stage1.vm.provision "ansible" do |ansible|

26

Page 28: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

ansible.playbook = "playbook-stage1.yml"

# Running the script as sudo grants us root permissions on the

# virtual machine, we need this since we are installing

# new packages

ansible.sudo = true

end

end

# Create virtual machine for Stage2 (MySQL)

config.vm.define "stage2" do |stage2|

# In this case we also give the machine an ip address to allow

# direct connection to the database to run tests

stage2.vm.network "private_network", ip: "192.168.1.3"

stage2.vm.network "forwarded_port", guest: 8080, host: 8087

stage2.vm.provision "shell", inline: <<-SHELL

sudo apt-get update

sudo apt-get install -y python

SHELL

stage2.vm.provision "ansible" do |ansible|

ansible.playbook = "playbook-stage2.yml"

ansible.sudo = true

end

end

# Create virtual machine for Stage3 (Google Cloud)

config.vm.define "stage3" do |stage3|

stage3.vm.box = "google/gce"

stage3.vm.provider :google do |google, override|

# This is out private informations section

google.google_project_id = "#{project_id}"

google.google_client_email = "#{service_account_mail}"

google.google_json_key_location = "#{json_private_key}"

# In this section we describe the machine we want to create

# Define the name of the instance.

google.name = "#{instance_name}"

# Set the zone where the instance will be located.

# To find out available zones:

# ‘gcloud compute zones list‘.

27

Page 29: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

google.zone = "europe-west1-d"

# Set the machine type to use. To find out available types:

# ‘gcloud compute machine-types list --zone asia-east1-c‘.

google.machine_type = "n1-standard-1"

# Set the machine image to use. To find out available images:

# ‘£ gcloud compute images list‘.

google.image = "ubuntu-1604-xenial-v20170202"

# We override the default connection settings to match those

# in our RSA keys

override.ssh.username = "#{ssh_user_name}"

override.ssh.private_key_path = "~/.ssh/id_rsa"

end

stage3.vm.provision "shell", inline: <<-SHELL

sudo apt-get update

sudo apt-get install -y python

SHELL

stage3.vm.provision "ansible" do |ansible|

ansible.playbook = "playbook-stage3.yml"

ansible.verbose = true

ansible.sudo = true

end

end

end

28

Page 30: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Ansible - playbook-stage1.yml

Questo e lo script di Ansible per il provisioning della prima macchina vir-tuale. In questo caso viene semplicemente installato e configurato Tomcated effettuato il deploy dell’applicazione.

---

- hosts: all

vars_files:

- vars.yml

tasks:

- name: Ensure Tomcat 8 is installed.

apt:

name: tomcat8

state: installed

- name: Replace Old Java options for Tomcat 8.

lineinfile:

dest: /etc/default/tomcat8

regexp: ’^JAVA_OPTS’

line: ’JAVA_OPTS="-Djava.awt.headless=true \

-XX:+UseConcMarkSweepGC"’

state: present

- name: Set New Java options for Tomcat 8.

# We need to set these options because our application requires

# more memory than what is provided by default

lineinfile:

dest: /etc/default/tomcat8

insertafter: ’^JAVA_OPTS’

line: ’JAVA_OPTS="${JAVA_OPTS} -Xms1024m \

-Xmx1024m -XX:MaxPermSize=256m"’

state: present

- name: Restart Tomcat 8 with the new options.

service:

name: tomcat8

state: restarted

enabled: yes

- name: Change /var/lib/tomcat8 permissions.

# When created tomcat8 directory is owned by root, we restore

# the correct ownership to allow tomcat to create his own files

29

Page 31: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

file:

path: /var/lib/tomcat8

owner: tomcat8

group: tomcat8

- name: Deploy application.

# To deploy the application we just need to copy the war package

# inside the webapps directory in tomcat home directory

become: yes

become_user: root

copy:

src: sm-shop/target/{{ snapshot_name }}

dest: /var/lib/tomcat8/webapps/sm-shop.war

30

Page 32: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Ansible - playbook-stage2.yml

Questo e lo script di Ansible per il provisioning della seconda macchinavirtuale. In questo caso, oltre ad installare Tomcat, viene installato e con-figurato il server MySQL, creato e popolato il database per l’applicazione ecreato l’utente per la connessione al database.

---

- hosts: all

vars_files:

- vars.yml

tasks:

- name: Ensure Tomcat 8 is installed.

apt:

name: tomcat8

state: installed

- name: Replace Old Java options for Tomcat 8.

lineinfile:

dest: /etc/default/tomcat8

regexp: ’^JAVA_OPTS’

line: ’JAVA_OPTS="-Djava.awt.headless=true

-XX:+UseConcMarkSweepGC"’

state: present

- name: Set New Java options for Tomcat 8.

# We need to set these options because our application requires

# more memory than what is provided by default

lineinfile:

dest: /etc/default/tomcat8

insertafter: ’^JAVA_OPTS’

line: ’JAVA_OPTS="${JAVA_OPTS} -Xms1024m

-Xmx1024m -XX:MaxPermSize=256m"’

state: present

- name: Restart Tomcat 8 with the new options.

service:

name: tomcat8

state: restarted

enabled: yes

- name: Change /var/lib/tomcat8 permissions.

# When created tomcat8 directory is owned by root, we restore

31

Page 33: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

# the correct ownership to allow tomcat to create his own files

file:

path: /var/lib/tomcat8

owner: tomcat8

group: tomcat8

- name: Ensure MySQL server is installed.

apt:

name: "{{ item }}"

state: installed

with_items:

- mysql-server

- mysql-client

- python-mysqldb

- name: Ensure MySQL server is running.

service:

name: mysql

state: started

enabled: yes

- name: Copy the mysqld.cnf

# This configuration file contains the setting to allow remote

# connection to the database

become: yes

become_user: root

copy:

src: mysqld.cnf

dest: /etc/mysql/mysql.conf.d/mysqld.cnf

- name: Restart MySQL

service:

name: mysql

state: restarted

- name: Create and populate SALESMANAGER MySQL database

# Using the import function we automatically execute the given

# SQL script on creation

mysql_db:

name: SALESMANAGER

state: import

target: /vagrant/SALESMANAGER-dump.sql

- name: Copy static data

32

Page 34: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

# These are the files where the CMS saves static images

copy:

src: "{{ item.src }}"

dest: "{{ item.dest }}"

owner: tomcat8

group: tomcat8

with_items:

- { src: ’StoreRepository.dat’,

dest: ’/var/lib/tomcat8/files/store/’ }

- { src: ’FilesRepository.dat’,

dest: ’/var/lib/tomcat8/files/repos/’ }

- name: Create user for SALESMANAGER MySQL database

mysql_user:

name: "{{ db.user }}"

password: "{{ db.password }}"

host: "{{ item }}"

priv: "*.*:ALL,GRANT"

state: present

with_items:

- "{{ db.host }}"

- localhost

- name: Deploy application.

# To deploy the application we just need to copy the war package

# inside the webapps directory in tomcat home directory

become: yes

become_user: root

copy:

src: sm-shop/target/{{ snapshot_name }}

dest: /var/lib/tomcat8/webapps/sm-shop.war

33

Page 35: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Ansible - playbook-stage3.yml

Questo e lo script di Ansible per il provisioning della terza macchina virtuale.A causa di diverse configurazioni di sicurezza rispetto alle macchine prece-denti, alcuni comandi sono stati leggermente modificati. Nonostante tuttiil risultato e identico rispetto all’esecuzione dello script per l’installazionedella macchina virtuale precedente.

---

- hosts: all

vars_files:

- vars.yml

tasks:

- name: Ensure Tomcat 8 is installed.

apt:

name: tomcat8

state: installed

- name: Replace Old Java options for Tomcat 8.

lineinfile:

dest: /etc/default/tomcat8

regexp: ’^JAVA_OPTS’

line: ’JAVA_OPTS="-Djava.awt.headless=true

-XX:+UseConcMarkSweepGC"’

state: present

- name: Set New Java options for Tomcat 8.

# We need to set these options because our application requires

# more memory than what is provided by default

lineinfile:

dest: /etc/default/tomcat8

insertafter: ’^JAVA_OPTS’

line: ’JAVA_OPTS="${JAVA_OPTS} -Xms1024m

-Xmx1024m -XX:MaxPermSize=256m"’

state: present

- name: Restart Tomcat 8 with the new options.

service:

name: tomcat8

state: restarted

enabled: yes

- name: Change /var/lib/tomcat8 permissions.

34

Page 36: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

# When created tomcat8 directory is owned by root, we restore

# the correct ownership to allow tomcat to create his own files

file:

path: /var/lib/tomcat8

owner: tomcat8

group: tomcat8

- name: Ensure MySQL server is installed.

apt:

name: "{{ item }}"

state: installed

with_items:

- mysql-server

- mysql-client

- python-mysqldb

- name: Ensure MySQL server is running.

service:

name: mysql

state: started

enabled: yes

- name: Copy static data

# These are the files where the CMS saves static images

copy:

src: "{{ item.src }}"

dest: "{{ item.dest }}"

owner: tomcat8

group: tomcat8

with_items:

- { src: ’StoreRepository.dat’,

dest: ’/var/lib/tomcat8/files/store/’ }

- { src: ’FilesRepository.dat’,

dest: ’/var/lib/tomcat8/files/repos/’ }

- name: Create user for SALESMANAGER MySQL database

mysql_user:

name: "{{ db.user }}"

password: "{{ db.password }}"

host: "{{ item }}"

priv: "*.*:ALL,GRANT"

state: present

with_items:

- "{{ db.host }}"

35

Page 37: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

- localhost

- name: Create SALESMANAGER MySQL database

# Due to different security setting in this case we have to

# create the database and then populate it at a later time

mysql_db:

name: SALESMANAGER

state: present

- name: Populate SALESMANAGER MySQL database

mysql_db:

name: SALESMANAGER

login_user: "{{ db.user }}"

login_password: "{{ db.password }}"

state: import

target: /vagrant/SALESMANAGER-dump.sql

- name: Deploy application.

become: yes

become_user: root

copy:

src: sm-shop/target/{{ snapshot_name }}

dest: /var/lib/tomcat8/webapps/sm-shop.war

36

Page 38: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

Bibliografia

[1] Gene Kim, Jez Humble, Patrick Debois & John Willis. The DevOpsHandbook. IT Revolution Press, 2016.

[2] Jeff Geerling. Ansible for DevOps. Leanpub, 2015.

[3] AnsibleWebsite: https://www.ansible.com/Wiki: https://en.wikipedia.org/wiki/Ansible_(software)Github: https://github.com/ansible/ansible

[4] ChefWebsite: https://www.chef.io/Wiki: https://en.wikipedia.org/wiki/Chef_(software)Github: https://github.com/chef/chef

[5] PuppetWebsite: https://puppet.com/Wiki: https://en.wikipedia.org/wiki/Puppet_(software)Github: https://github.com/puppetlabs/puppet

[6] VagrantWebsite: https://www.vagrantup.com/Wiki: https://en.wikipedia.org/wiki/Vagrant_(software)Github: https://github.com/mitchellh/vagrant

[7] JenkinsWebsite: https://jenkins.io/Wiki: https://en.wikipedia.org/wiki/Jenkins_(software)Github: https://github.com/jenkinsci

[8] JMeterWebsite: http://jmeter.apache.org/Wiki: https://en.wikipedia.org/wiki/Apache_JMeter

[9] JMeter - Building a Web Test Planhttp://jmeter.apache.org/usermanual/build-web-test-

plan.html

37

Page 39: Progetto e implementazione di una pipeline di sviluppo software con tecnologie DevOps

[10] JMeter - Recording Testshttp://jmeter.apache.org/usermanual/jmeter_proxy_step_by_

step.pdf

[11] SeleniumWebsite: http://www.seleniumhq.org/Wiki: https://en.wikipedia.org/wiki/Selenium_(software)Github: https://github.com/SeleniumHQ/selenium

[12] ShopizerWebsite: http://www.shopizer.comWiki: https://github.com/shopizer-ecommerce/shopizer/wikiGithub: https://github.com/shopizer-ecommerce/shopizer

[13] Setup Development Environment with Vagrant on Google ComputeEnginehttps://realguess.net/2015/09/07/setup-development-

environment-with-vagrant-on-google-compute-engine/

[14] Compute Engine Management with Puppet, Chef, Salt, and Ansiblehttps://cloud.google.com/solutions/google-compute-engine-

management-puppet-chef-salt-ansible

[15] Provider ufficiale per Google Compute Engine (GCE) di Vagranthttps://github.com/mitchellh/vagrant-google

38