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