tdd e continuous delivery sull'infrastruttura
DESCRIPTION
Grazie al fatto che molti dei valori e dei principi del movimento DevOps sono in comune con quelli di Extreme Programming, negli ultimi siamo riusciti ad applicare anche molte dellle pratiche in un contesto più ampio di quello nel quale erano state concepite. In questa sessione mi piacerebbe condividere il percorso che ho seguito per sviluppare una nuova infrastruttura in TDD e per arrivare ad un processo automatico in grado di deployare in produzione tutti i cambiamenti con un click.TRANSCRIPT
Filippo Liverani@filippo
agile + IT operations?
photo credit: https://www.flickr.com/photos/kalexanderson/6354182139/
1. test driven development2. continuous delivery3. nella pratica
Test Driven Development
photo credit: https://www.flickr.com/photos/pagedooley/4308431673/
le 3 leggi del TDD
photo credit: https://www.flickr.com/photos/oldpatterns/5837733407/
1
Non scriverai codice di produzione finché non avrai scritto un test che fallisce
2Non scriverai più di un test che sia
sufficiente a provocare un fallimento, e la non compilazione è
un fallimento
3Non scriverai più codice di
produzione di quanto ne serva per passare il test corrente
piccoli cambiamenti incrementali
sistema sempre funzionante
i fallimenti devono essere risolti subito
perchè?abbatte la complessità
soluzione di un problema complesso → soluzione di problemi più semplici
i beneficicriterio di accettazione implicito
specifica eseguibile
suite di regressione completa
feedback immediato e continuo
le difficoltà?richiede disciplina
cambiare le abitudini è difficile
il management non capisce la qualità interna
continuous delivery
photo credit: https://www.flickr.com/photos/afoncubierta/9049067504/
beneficisi vede se abbiamo costruito la cosa giustarelease frequenti -> meno rischi per release
indicatore reale di avanzamento
obiettiviaumentare la qualitàdiminuire il cycle time
CYCLE TIME = tempo per portare una modifica di una linea di codice in produzione
continuous integration
photo credit: https://www.flickr.com/photos/dps/136565237/
il problemail costo per l'integrazione aumenta con:
numero di bug
numero di componenti
tempo trascorso dall'ultima integrazione
la soluzione?integrazioni rapide e continue senza bloccare il processo
i beneficii problemi si trovano subito si trovano facilmentemeno rischi
feedback rapidonessun punto cieco nel processopredizioni più accurate
le 10 pratiche
photo credit: https://www.flickr.com/photos/edenpictures/3813227079/
1un solo repository
tutto quello che serve deve essere versionato
2 build automatica
artefatto finale pronto per la produzioneogni passo automatizzato
dai sorgenti ai test che giranonessun intervento manuale
nessuna modifica dell'ambiente
3test automatici
4commit frequenti
al MASSIMO una volta al giorno
lavorare sul trunk
build di riferimentomonitor dello stato del repository
massima priorità alla build funzionante
5 integrazione a ogni commit
<10minfeedback immediatodivisione in stage (pipeline)
6build veloce
stessi problemi che si verificherebbero in produzioneambiente identico
7su un clone di produzione
sistema operativo libreriehardware rete
demo e test sempre disponibili
chiaramente identificabile da tutti
8 ultimo artefatto accessibile
comunicazione immediata dello stato
pubblicamente accessibile
9 tutti vedono cosa succede
riduzione dei tempiriduzione degli errorirollback
10 deploy automatico
1. TESTARE2. AUTOMATIZZARE3. VELOCIZZARE
come arrivarci?
delivery pipeline
photo credit: https://www.flickr.com/photos/abuaiman/6267986277/
pipelineimplementazione automatizzata
del processo di build, deploy, test e rilascio
1. visibilità2. feedback3. controllo
strutturasequenza di stage
se uno stage fallisce la pipeline si blocca
ogni commit genera una nuova pipeline
infrastructure as code
photo credit: https://www.flickr.com/photos/mwichary/2348383457/
DevOps+
virtualizzazione e cloud
->
anche l’infrastruttura è codice
collaborazione + automazione
trasferimento della conoscenza
tooling
la potenza del testo
i beneficiripetibilità
tracciabilità
manutenibilità
velocità
immutable servers
photo credit: https://www.flickr.com/photos/mwichary/2348383457/
approccio tradizionalecambiamenti e disallineamenti -
>
snowflake server
sincronizzazione
creazione immagine
provisioning istanza
applicazione cambiamento
applicazione cambiamento
cambiamento cambiamento
immutable server
creazione immagine
provisioning istanza
cambiamento
creazione immagine
provisioning istanza
nella pratica
photo credit: https://www.flickr.com/photos/jurvetson/489257240/
source coderepository
CI serverproduction
image
commit
test image
dev box
checkout
provision run tests
provision
$ git init git-cookbook$ cd git-cookbook
name "git"version "0.1.0"
git-cookbook/metadata.rb
Test Kitchen
$ kitchen init --driver=kitchen-vagrant
---driver: name: vagrant
provisioner: name: chef_solo
platforms: - name: ubuntu-14.04
suites: - name: default run_list: - recipe[git::default]
git-cookbook/.kitchen.yml
require 'serverspec'
set :backend, :exec
describe package('git') do it { should be_installed }end
git-cookbook/test/integration/server/serverspec/git_spec.rb
$ kitchen test
====================================== Recipe Compile Error ======================================== Chef::Exceptions::RecipeNotFound -------------------------------- could not find recipe default for cookbook git>>>>>> Converge failed on instance <default-ubuntu-1404>.
include_recipe "apt"
package "git"
git-cookbook/recipes/default.rb
name "git"version "0.1.0"
depends "apt"
git-cookbook/metadata.rb
source "https://api.berkshelf.com" metadata
git-cookbook/Berksfile
$ kitchen test
Package "git" should be installed Finished in 0.21441 seconds (files took 0.36317 seconds to load) 1 example, 0 failuresFinished verifying <default-ubuntu-1404> (0m33.52s).-----> Kitchen is finished. (1m31.77s)
{ "variables": { "aws_access_key": null, "aws_secret_key": null },
...
packer.json - 1
...
"builders": [{ "type": "amazon-ebs", "access_key": "{{user `aws_access_key`}}", "secret_key": "{{user `aws_secret_key`}}", "region": "eu-west-1", "ami_virtualization_type": "hvm", "source_ami": "ami-28ff505f", "instance_type": "t2.micro", "ssh_username": "ubuntu", "ami_name": "git" }]
...
packer.json - 2
... "provisioners": [ { "type": "chef-solo", "cookbook_paths": ["berks-cookbooks"], "run_list": ["git::default"] } ]}
packer.json - 3
source 'https://api.berkshelf.com' cookbook 'git', path: './git-cookbook'
Berksfile
$ berks vendor
$ packer build \ -var 'aws_access_key=YOUR ACCESS KEY' \ -var 'aws_secret_key=YOUR SECRET KEY' \ packer.json
==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created:
eu-west-1: ami-ac3199db
{ "AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Git box",
"Parameters" : { "AmiId" : { "Type" : "String" } },
...
cloudformation.json - 1
...
"Resources" : { "Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : { "Ref" : "AmiId" }, "KeyName" : "git-box-key", "InstanceType" : "t2.micro" } } }}
cloudformation.json - 2
$ aws cloudformation create-stack \ --stack-name git-box \ --region eu-west-1 \ --template-body file://./cloudformation.json --parameters ParameterKey=AmiId,ParameterValue=ami-ac3199db
{ "StackId": "arn:aws:cloudformation:eu-west-1:422553113847:stack/git-box/978445e0-5f78-11e4-95a6-507bb00bdca0"}
risorse
https://github.com/filippo-liverani/test-driven-infrastructure
grazie!