Continuous Delivery -...

49
Continuous Delivery Architettura dei Sistemi Software 27 maggio 2016

Transcript of Continuous Delivery -...

Continuous Delivery

Architettura dei Sistemi Software

27 maggio 2016

Elementi abilitanti

Prima di dare una definizione e trattare il mondo della Continuous Delivery è necessario analizzare gli elementi che la abilitano, ovvero:

• DevOps

• Continuous Integration

DevOps

Metodologia di lavoro in cui si vuole andare a massimizzare la comunicazione, la collaborazione e l’integrazione tra gli sviluppatori e tutti gli altri professionisti dell’IT (in particolare l’area operational) per tutto il ciclo di vita del software.

Motivazioni

Aiuta ad affrontare in modo sano gli sprechi legati alla produzione e alla messa in esercizio del software.

Riduce le frizioni tra persone con diverse competenze, favorisce la diffusione delle conoscenze e la visione end-to-end.

Principi

Applicare il System thinking visualizzando il flusso di di lavoro nella sua interezza.

Estendere i cicli di feedback e diffondere le buone pratiche imparate in un settore.

Massimizzare Continuous Improvement, la sperimentazione continua e la cultura no blame.

Continuous Integration

Pratica dello sviluppo software originata dall’eXtreme Programming, in cui la codebase è gestita da un team di diverse persone che continuamente integrano le proprie modifiche in un sistema di controllo versione condiviso.

Ad ogni integrazione viene eseguito in modo automatico un set predefinito di task che verifica la qualità delle modifiche.

eXtreme Programming

eXtreme Programming (XP) è una metodologia di lavoro dello sviluppo SW che si basa su un set chiave di 5 valori:

1) semplicità 2) comunicazione 3) feedback 4) coraggio 5) rispetto

Cosa significa integrare?

La codebase risiede in un sistema di controllo versione remoto candidato al rilascio di cui ogni sviluppatore ha una copia locale.

Ciascun sviluppatore integra le proprie modifiche frequentemente (almeno 1 volta al giorno) e si occupa di allineare la propria versione locale.

Branches vs Master

Alcuni team usano “Feature Branching”, altri lavorano sempre sul master branch, ma vale sempre la regola dell’integrare frequentemente.

In entrambi i casi è responsabilità dello sviluppatore quello di verificare in locale che il proprio codice passi un set minimo di test prima di integrare.

Testing automatico

Per ogni integrazione, vengono eseguiti in un ambiente quanto più simile alla produzione un set di verifiche che provano il corretto funzionamento del sistema:

• build • unit test / integration test • UAT (user acceptance test) • stress test

Vantaggi

Riduce sensibilmente i problemi di integrazione permettendo al team di sviluppare SW più coeso rapidamente e con meno bug.

Lo sviluppatore ha feedback veloce sul proprio lavoro e ha la sicurezza di poter avere sempre una versione funzionante del codice.

Viene ridotto l’errore umano.

Svantaggi??

Non ci sono significativi svantaggi nell’adozione delle pratiche di CI.

Dal punto di vista dei membri del team ci deve però essere una presa di responsabilità condivisa:

• evitare il più possibile di “rompere la build” • risolvere eventuali problemi il più

velocemente possibile

Operazioni da effettuare

Come funziona una pipeline di Continuous Integration?

• push di modifiche su SCM • post commit hook verso job di CI • build • test • post build (e.g. email)

Integrazione “In-House”

Libertà di installazione di tutti gli strumenti necessari.

Controllo totale dell’infrastruttura e del tool selezionato: Jenkins, Drone, SnapCI, etc etc

Manutenzione è a carico del team. Scalabilità non è sempre ottenibile in modo semplice.

Integrazione “Cloud”

Mantiene tutti i benefici di una soluzione “In house” garantendo inoltre una semplice scalabilità del sistema.

Servizi come AWS accoppiati a tool quali Chef, Packer e Terraform consentono di distruggere e ricreare ambienti di CI in modo automatico.

Integrazione “As a Service”

Esistono svariati servizi “As a Service” che forniscono a diverse tariffe ambienti di CI (e.g. Travis, Codeship etc etc).

Soluzione valida per progetti abbastanza “standard” dove non serve una configurazione troppo personalizzata.

Adatta per progetti opensource.

Continuous Delivery

Definizione di Martin Fowler:

“Continuous Delivery is a software development discipline where you build software in such a way that the software can be released to production at any time. ” *

* http://bit.ly/1cqYbyx

Continuous Delivery

Definizione del team XPeppers:

“Continuous Delivery is nothing more than reducing the stress you get when you deliver business value to the customer.”

Motivazioni

Diventa facile per il team capire se si sta costruendo la cosa giusta.

Si vanno a ridurre tutti i rischi legati a fare un numero ridotto di deploy.

Si è in grado di costruire, testare e rilasciare i nostri prodotti in modo automatico, veloce e con maggiore frequenza.

Motivazioni

Da un punto di vista legato al business, l’adozione della Continuous Delivery riduce il “cycle time” ovvero il tempo necessario per mettere in produzione una feature richiesta.

Si riesce quindi a valutare l’impatto della modifica velocemente e si possono applicare ragionamenti di mercato in base al feedback ricevuto.

CD vs CI

Verificare tramite l’adozione della Continuous Integration che il sistema funzioni non è sufficiente.

Applicando la Continuous Delivery diamo per assodato che il software ha valore solo se messo in produzione.

CD non è Continuous Deployment

In un progetto in cui si applica Continuous Deployment, le modifiche vanno subito in produzione una volta passata la fase di verifica di tutte le sue componenti.

In un progetto in cui si applica Continuous Delivery, le modifiche vengono rese disponibili al deployment, che avverrà a seguito di un intervento umano.

Continuous Delivery è cultura

Si ricerca il feedback in modo continuativo e si continua a migliorare il proprio processo.

Si cerca di automatizzare il più possibile, e tutti partecipano dalla scrittura del codice alla messa in produzione (DevOps).

Si smette di guardare al deploy come ad un momento rischioso e si inizia a considerarlo come un’operazione triviale.

Continuous Delivery

Automazione

Ripetibilità

Affidabilità

—> Confidenza

Pratiche tecniche

Scrittura di test (Unit Test, Integration Test, UAT).

Scrittura di codice applicativo.

Creazione e migrazione di database.

Creazione e provisioning della macchina

Deploy a comando in modo semplice.

Schermata di deploy

Il deploy al giorno d’oggi?

In molte realtà il deploy è tuttavia ancora visto come un’operazione complessa e difficile.

Spesso c’è ancora una chiara distinzione tra sviluppo e operation.

Continuous Delivery anti pattern

In tali realtà i più comuni anti pattern sono:

• Assenza di test • Deploy manuale • Snowflake environment • Collaborazione mancante o ridotta

Esempio reale: applicazione

• applicazione Java • REST api • logica di business

• database relazionale

• aws (staging/production)

• applicazione AngularJs • consuma api, interfaccia utente

Esempio reale: CD server

Come Continuous Delivery server utilizzeremo Jenkins CI.

Jenkins è scritto in Java ed open source quindi ha una buona community alle spalle.

Jenkins è molto flessibile, ha una vastissima quantità di plugin e si presta bene per progetti Java.

Step 1

Nessuna automazione!

• build e test eseguiti in modo manuale sulla propria macchina

• migrazioni manuali del db

• deploy manuale sugli ambienti usando uno script

Motivazioni

Se il team sta affrontando un problema nuovo e non ha mai lavorato applicando la Continuous Delivery è importante spendere il tempo iniziale del progetto imparando a conoscere il dominio e i singoli tool.

Non ha senso fare cose over complicate senza motivazione!

Step 2

Creiamo nel nostro server Jenkins un primo job (unità di lavoro) che rappresenti la pipeline.

• il job viene eseguito ad ogni commit su SCM

• job diviso in stages: unit test, build (no IT)

• database creato e migrato tramite tool più adatti al nostro approccio incrementale

Liquibase e Flyway

Permettono di ricreare un db da scratch e di migrare in modo deterministico da una versione ad una più recente.

$ flyway migrate -url=... -user=... -password=...

Migrazione:

V1__Create_person_table.sql

create table PERSON ( ID int not null, NAME varchar(100) not null);

Fetch Unit Tests Build

Build

Migrate Deploy

Deploy

Step 3

Gli errori più comuni a questo punto sono legati a configurazioni/wiring incorretti.

Vengono introdotti bug nel sistema che sono riscontrabili sono in ambiente di QA o in produzione.

Integration Test Stage

In seguito agli unit test andiamo a verificare come il sistema si integra con database, code e servizi esterni.

I test di integrazione sono più lenti, hanno uno scope più largo e danno ulteriore confidenza al team.

Dovrebbero essere presenti in numero molto minore rispetto agli unit test.

Fetch Unit Tests Build

Build

Migrate Integration Test

Integration

Migrate Deploy

Deploy

Step 4

E’ fondamentale fare in modo che l’artefatto finale prodotto dalla nostra pipeline sia unico e rilasciabile su qualsiasi ambiente.

Solo in questo modo siamo sicuri che il software destinato a produzione sia corretto al 100%.

L’ostacolo più grande è rappresentato dalle configurazioni che differiscono da ambiente ad ambiente.

Configurazioni su macchina target

Una soluzione valida consiste nel generare un artefatto che sia agnostico rispetto alle configurazioni.

Le configurazioni possono essere messe a disposizione nella macchina che ospiterà l’applicazione.

E’ possibile anche avere un servizio remoto che in base all’ambiente da cui arrivano le chiamate fornisca le configurazioni necessarie.

Step 5

Raggiunto un certo livello di confidenza si può andare ad aggiungere ulteriori livelli di testing alla propria pipeline in modo da massimizzare l’automazione.

Con gli User Acceptance Test (UAT) andiamo a testare in modalità black box il nostro sistema, replicando il comportamento dell’utente.

Spesso siamo anche interessati a conoscere come si comporta il nostro sistema sotto stress utilizzando degli stress test.

Cucumber/Gherkin

E’ un Domain Specific Language (DSL) che permette di descrivere in un modo leggibile anche per i non tecnici quale comportamento dovrebbe avere il nostro sistema.

1: Feature: Some terse yet descriptive text of what is desired 2: 3: Scenario: Some determinable business situation 4: Given some precondition 5: And some other precondition 6: When some action by the actor 7: And some other action 8: And yet another action 9: Then some testable outcome is achieved10: And something else we can check happens too

Fetch Unit Tests Build

Build

Migrate Integration Test

Integration

UAT Stress Test

Acceptance

Migrate Deploy

Deploy

Esempio reale: CD server

Conclusioni I

Continuous Delivery è una pratica che permette di poter rilasciare una specifica versione in qualsiasi momento in produzione.

E’ una pratica che permette di rilasciare software in modo iterativo e incrementale mantenendo alti standard valutabili in base a metriche reali.

Conclusioni II

L’applicazione della Continuous Delivery risulta più efficiente nelle realtà che applicano i principi della cultura DevOps.

Non esiste un template predefinito per realizzare una pipeline di Continuous Delivery, ma ci sono un set di stage (Unit Test/Integration Test etc etc) che sono un buon punto di partenza su cui costruire una pipeline adatta alle proprie necessità.

Recommended reading

http://amzn.to/1SW2pYQ http://amzn.to/1WgvG2V

Letture consigliate

http://amzn.to/1UJhPkz

Letture consigliate