Continuous Delivery
Transcript
Continuous Delivery
Continuous Delivery Architettura dei Sistemi Software 27 maggio 2016 Paolo D’Incau [email protected] www.xpeppers.com 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) 2) 3) 4) 5) semplicità comunicazione feedback coraggio 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 ); Build Deploy Fetch Unit Tests Build Migrate 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. Build Integration Deploy Fetch Unit Tests Build Migrate Integration Test Migrate 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 achieved 10: And something else we can check happens too Build Integration Acceptance Deploy Fetch Unit Tests Build Migrate Integration Test UAT Stress Test Migrate 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à. Letture consigliate Recommended reading http://amzn.to/1SW2pYQ http://amzn.to/1WgvG2V Letture consigliate http://amzn.to/1UJhPkz