Ciao, Habr! In passato mi sono lamentato della vita nella penultima paradigmi Infrastructure as code senza offrire soluzioni per la situazione attuale. Oggi sono tornato per raccontare quali approcci e pratiche possono aiutare a uscire dall'abisso della disperazione e raddrizzare la situazione.

Nell'articolo precedente ho condiviso le mie impressioni su questo settore, ho cercato di riflettere sulla situazione attuale in quest'area e ho persino suggerito che pratiche standard, conosciute da tutti gli sviluppatori, potrebbero essere utili. Potrebbe sembrare che ci fossero molte lamentele sulla vita, ma mancavano proposte per uscire dalla situazione attuale.
Chi siamo, dove siamo e quali sono i nostri problemi
Ora ci troviamo nel Sre Onboarding Team, composto da sei programmatori e tre ingegneri di infrastruttura. Tutti noi stiamo cercando di scrivere Infrastructure as code (IaC). Lo facciamo perché in linea di massima sappiamo scrivere codice e abbiamo un background di sviluppatori di livello 'sopra la media'.
- Abbiamo un insieme di vantaggi: un certo background, conoscenza delle pratiche, capacità di scrivere codice e voglia di imparare cose nuove.
- C'è una parte pendente, che è anche un aspetto negativo: la mancanza di conoscenze sulla scienza dei materiali dell'infrastruttura.
Stack tecnologico che utilizziamo nel nostro IaC.
- Terraform per creare risorse.
- Packer per creare immagini. Questi sono immagini di Windows e CentOS 7.
- Jsonnet per realizzare una potente build in drone.io, oltre che per generare packer json e i nostri moduli Terraform.
- Azure.
- Ansible durante la preparazione delle immagini.
- Python per servizi ausiliari e script di provisioning.
- E tutto questo in VSCode con plugin condivisi tra i membri del team.
L'output del mio era: ho cercato di infondere (soprattutto in me stesso) ottimismo, volevo dire che proveremo ad utilizzare gli approcci e le pratiche che conosciamo per affrontare le difficoltà e le complessità presenti in questo campo.
Attualmente stiamo affrontando problemi con l'IaC:
- Imperfezione degli strumenti e dei mezzi per sviluppare il codice.
- Lento dispiegamento. L'infrastruttura è parte del mondo reale, e questo può richiedere tempo.
- Mancanza di approcci e pratiche.
- Siamo principianti e non sappiamo molto.
L'estreme programming (XP) corre in aiuto.
Tutti gli sviluppatori conoscono bene l'estreme programming (XP) e le pratiche che lo accompagnano. Molti di noi hanno lavorato con questo approccio, e ha avuto successo. Quindi, perché non sfruttare i principi e le pratiche che ne derivano per affrontare le difficoltà infrastrutturali? Abbiamo deciso di applicare questo approccio e vedere cosa ne risulta.
Verifica dell'applicabilità dell'approccio XP al tuo settoreEcco una descrizione dell'ambiente in cui XP si adatta bene, e come si relaziona con noi:
1. Requisiti software in continua evoluzione. Era chiaro qual era l'obiettivo finale. Ma nei dettagli è possibile variare. Siamo noi a decidere quale direzione prendere, quindi i requisiti cambiano periodicamente (soprattutto da parte nostra). Prendendo in considerazione il team SRE, che automatizza da solo e stabilisce autonomamente i requisiti e l'ambito del lavoro, questo punto si applica bene.
2. Rischi causati da progetti a tempo fisso che utilizzano nuove tecnologie. Possiamo incontrare rischi nell'uso di tecnologie a noi sconosciute. E questo è sicuramente il nostro caso. L'intero progetto si basa sull'uso di tecnologie con cui non siamo completamente familiari. Questo è un problema costante, poiché nel settore delle infrastrutture emergono continuamente nuove tecnologie.
3,4. Piccola squadra di sviluppo estesa e co-locata. La tecnologia che stai utilizzando consente test automatizzati a livello unitario e funzionale. Questi due punti non si adattano esattamente a noi. Innanzitutto, non siamo un team co-locato, e in secondo luogo, siamo nove persone, che possono essere considerate una grande squadra. Tuttavia, secondo alcune definizioni, una 'grande' squadra è composta da 14 o più persone.
Esaminiamo alcune pratiche dell'XP e come influiscono sulla velocità e sulla qualità del feedback.
Il principio del ciclo di feedback nell'XP
Nel mio modo di vedere, il feedback è la risposta alla domanda se sto facendo bene, se stiamo andando nella giusta direzione. Nell'XP c'è un diagramma molto interessante: il ciclo di feedback temporale. La cosa interessante è che quanto più in basso ci troviamo, più velocemente possiamo ottenere l'output necessario per rispondere alle domande essenziali.

È un tema piuttosto interessante da discutere, poiché nel settore IT è possibile ottenere rapidamente un sistema operativo. Immagina quanto sarebbe frustrante lavorare a un progetto per sei mesi e poi scoprire che fin dall'inizio c'era un errore. Questo può accadere sia nella progettazione che nella realizzazione di sistemi complessi.
Nel nostro caso, IaC ci aiuta con il feedback. Faccio subito una piccola correzione allo schema sopra: il piano di rilascio non segue un ciclo mensile, ma avviene più volte al giorno. A questo ciclo sono legate alcune pratiche che esamineremo più in dettaglio.
Importante: il feedback può diventare la soluzione per tutti i problemi sopra menzionati. Insieme alle pratiche XP, può sollevarti dall'abisso della disperazione.
Come tirarsi fuori dall'abisso della disperazione: tre pratiche
Test
I test vengono menzionati due volte nel ciclo di feedback XP. Non è casuale. Sono estremamente importanti per tutta la tecnica della programmazione estrema.
Si presume che tu abbia test Unitari e di Accettazione. I primi ti forniscono feedback in pochi minuti, i secondi in qualche giorno, motivo per cui sono scritti più a lungo e eseguiti meno frequentemente.
Esiste una classica piramide di test che mostra che ci devono essere più test di un certo tipo.

Come si applica questo schema al nostro progetto IaC? In realtà... non si applica affatto.
- Nonostante ci dovrebbe essere un gran numero di unit test, in realtà non possono essere così tanti. O sono molto indirettamente collegati a qualcosa. Possiamo dire che in effetti non li scriviamo affatto. Tuttavia, ecco alcune applicazioni per questi test che siamo riusciti a realizzare:
- Test del codice su jsonnet. Questo è, ad esempio, il nostro pipeline di assemblaggio in drone, che è abbastanza complesso. Il codice su jsonnet è ben coperto dai test.
Utilizziamo questo . - Test degli script che vengono eseguiti all'avvio delle risorse. Gli script sono in Python, e quindi anche i test su di essi possono essere scritti.
- Test del codice su jsonnet. Questo è, ad esempio, il nostro pipeline di assemblaggio in drone, che è abbastanza complesso. Il codice su jsonnet è ben coperto dai test.
- È potenzialmente possibile controllare la configurazione nei test, ma noi non facciamo così. C'è anche la possibilità di configurare il controllo delle regole per la configurazione delle risorse tramite . Tuttavia, per terraform ci sono solo controlli di base, ma sono stati scritti molti scenari di verifica per AWS. E noi siamo su Azure, quindi non si adatta di nuovo.
- Test di integrazione dei componenti: qui dipende da come li classificano e dove li posizionano. Ma in linea di principio funzionano.
Ecco come appaiono i test di integrazione.

Questo è un esempio di creazione di immagini in Drone CI. Per arrivarci, bisogna attendere 30 minuti affinché l'immagine Packer venga creata, poi altri 15 minuti perché vengano superati. Ma ci sono!Algoritmo di verifica delle immagini
- Prima di tutto, Packer deve preparare completamente l'immagine.
- Accanto al test c'è Terraform con uno stato locale, con cui distribuiamo questa immagine.
- Durante la distribuzione viene utilizzato un piccolo modulo, posizionato accanto, per lavorare più facilmente con l'immagine.
- Quando la VM è stata distribuita dall'immagine, si possono iniziare le verifiche. In gran parte, le verifiche vengono effettuate sulla macchina. Si controlla come sono stati eseguiti gli script all'avvio e come funzionano i demoni. A questo scopo, tramite ssh o winrm, accediamo alla macchina appena avviata e controlliamo lo stato della configurazione o se i servizi sono stati avviati.
- Una situazione simile si presenta anche con i test di integrazione nei moduli per Terraform. Ecco una tabella riepilogativa che spiega le caratteristiche di tali test.

Il feedback sulla pipeline è di circa 40 minuti. Tutto richiede molto tempo. Può essere usato per il regression testing, ma per lo sviluppo nuovo è assolutamente impossibile. Se ci si prepara molto, predisponendo running e script, si può ridurre a 10 minuti. Ma comunque non si tratta di test unitari che possono essere eseguiti in 5 secondi per 100 casi.
L'assenza di test unitari nella costruzione di immagini o moduli di Terraform spinge a delegare il lavoro a servizi separati, che possono semplicemente essere chiamati tramite REST, o a script Python.
Ad esempio, avevamo bisogno di fare in modo che all'avvio della macchina virtuale si registrasse nel servizio , e che all'eliminazione della macchina virtuale si cancellasse.
Poiché ScaleFT è un nostro servizio, siamo costretti a lavorare con esso tramite API. È stata scritta una wrapper che può essere chiamata per dire: «Accedi e cancella questo e quello». Essa conserva tutte le configurazioni e gli accessi necessari.
Ora possiamo scrivere test adeguati, poiché questo non differisce affatto dal software normale: si simula un qualche API, la si chiama e si osserva cosa succede.

Risultati dei test: i test unitari, che dovrebbero fornire un feedback all'OS in un minuto, non lo fanno. Tuttavia, i livelli di test superiori nella piramide forniscono risultati, ma risolvono solo una parte dei problemi.
Programmazione in coppia
I test sono sicuramente importanti. Si possono scrivere molti test, in diverse forme. Lavoreranno ai loro livelli e ci forniranno feedback. Ma il problema dei cattivi test unitari, che non forniscono il riscontro più veloce all'OS, resta. Allo stesso tempo, si desidera ancora un'OS veloce, con cui è facile e piacevole lavorare. Senza contare la qualità della soluzione finale. Fortunatamente, ci sono tecniche che permettono di ottenere un feedback ancora più veloce rispetto ai test unitari. Questa è la programmazione in coppia.
Quando si scrive codice, si desidera ricevere il feedback sulla sua qualità il più rapidamente possibile. Certo, si può scrivere tutto in un ramo di funzionalità (per non rompere nulla a nessuno), fare una pull request su GitHub, assegnare a qualcuno il cui parere conta, e attendere una risposta.
Ma si può aspettare a lungo. Le persone sono tutte occupate, e la risposta, anche se arriva, potrebbe non essere della massima qualità. Supponiamo che la risposta arrivi subito, il revisore ha capito immediatamente l'intero concetto, ma la risposta comunque arriva con ritardo, post factum. E invece si desidera farlo prima. Ecco perché la programmazione in coppia è finalizzata a questo: per ottenere feedback immediato, mentre si scrive.
Di seguito riporto gli stili della programmazione in coppia e la loro applicabilità nel lavoro su IaC:
1. Classico, Esperto+Esperto, cambio a tempo. Due ruoli – driver e navigator. Due persone. Lavorano sullo stesso codice e cambiano ruolo dopo un determinato intervallo di tempo precedentemente stabilito.
Consideriamo la compatibilità dei nostri problemi con lo stile:
- Problema: imperfezione degli strumenti, mezzi per lo sviluppo del codice.
Influenza negativa: sviluppo più lungo, ci rallentiamo, si interrompe il ritmo di lavoro.
Come affrontiamo: utilizziamo un altro tooling, un IDE condiviso e impariamo anche le scorciatoie. - Problema: distribuzione lenta.
Influenza negativa: aumenta il tempo per creare un pezzo di codice funzionante. Ci annoiamo mentre aspettiamo, le mani si tendono a fare qualcos'altro mentre si attende.
Come affrontiamo: non siamo riusciti a risolverlo. - Problema: mancanza di approcci e pratiche.
Impatto negativo: non si sa come fare bene e come fare male. Allunga il ricevimento di feedback.
Come affrontiamo: lo scambio di opinioni e pratiche nel lavoro a coppie quasi risolve il problema.
La principale difficoltà nell'applicazione di questo stile in IaC è il ritmo di lavoro irregolare. Nello sviluppo software tradizionale hai un'andatura molto regolare. Puoi impiegare cinque minuti e scrivere N. Spendere 10 minuti e scriverne 2N, 15 minuti – 3N. Qui, puoi spendere cinque minuti e scrivere N, e poi spendere altri 30 minuti per scrivere un decimo di N. Qui non sai nulla, hai un blocco. L'analisi richiede tempo e distrae dalla programmazione vera e propria.
Conclusione: nella sua forma pura non ci si adatta.
2. Ping-pong. Questo approccio prevede che un partecipante scriva un test, mentre l'altro si occupa della sua implementazione. Tenendo presente che gli Unit test sono complicati e che è necessario scrivere un test di integrazione che richiede molto tempo per la programmazione, tutta la facilità del ping-pong svanisce.
Posso dire che abbiamo provato a separare i compiti tra la progettazione dello script di test e la sua implementazione. Un partecipante creava lo script e in quest'area del lavoro era responsabile, aveva l'ultima parola. L'altro era incaricato dell'implementazione. Questo ha funzionato bene. La qualità dello script con questo approccio aumenta.
Conclusione: sfortunatamente, il ritmo di lavoro non consente di utilizzare il ping-pong come pratica di programmazione in coppia in IaC.
3. Strong Style. L'idea è che un partecipante diventa un navigatore autoritario, mentre l'altro assume il ruolo di driver esecutivo. In questo caso, il diritto decisionale spetta esclusivamente al navigatore. Il driver si limita a scrivere e può influenzare ciò che accade con le parole. I ruoli non cambiano a lungo.
Adatto per l'apprendimento, ma richiede forti soft skills. Qui ci siamo inceppati. La tecnica è stata difficile. E non si tratta nemmeno dell'infrastruttura.
Conclusione: potenzialmente applicabile, non desistiamo dai tentativi.
4. Mobbing, swarming e tutti gli stili noti, ma non elencati qui. Non li consideriamo, poiché non li abbiamo provati e non possiamo parlare di questo nel contesto del nostro lavoro.
Risultati generali sull'utilizzo del pair programming:
- Abbiamo un ritmo di lavoro irregolare che crea confusione.
- Ci siamo scontrati con soft skills non sufficientemente sviluppate. E l'area tematica non facilita il superamento di queste nostre carenze.
- Test lunghi e problemi con gli strumenti rendono la programmazione in coppia difficile.
5. Nonostante ciò, ci sono stati anche dei successi. Abbiamo ideato il nostro metodo "Convergenza – Divergenza". Descriverò brevemente come funziona.
Abbiamo partner fissi per alcuni giorni (meno di una settimana). Lavoriamo insieme su un compito. Per un certo periodo stiamo insieme: uno scrive, l'altro osserva, come un supporto. Poi ci separiamo per un po', ognuno lavora su attività indipendenti, poi ci riuniamo rapidamente, ci sincronizziamo, facciamo qualcosa insieme e ci separiamo di nuovo.
Pianificazione e comunicazione
L'ultimo gruppo di pratiche attraverso le quali si risolvono i problemi OS è l'organizzazione del lavoro stesso con i compiti. Qui rientra anche lo scambio di esperienze, che si trova al di fuori del lavoro in coppia. Esaminiamo tre pratiche:
1. Compiti tramite l'albero degli obiettivi. La gestione generale del progetto è organizzata attraverso un albero che si estende all'infinito nel futuro. Tecnologicamente, la gestione avviene tramite Miro. C'è un compito principale – un obiettivo intermedio. Da questo si diramano obiettivi più piccoli o gruppi di attività. Da questi scaturiscono le singole attività. Tutte le attività vengono create e gestite su questa bacheca.

Questo schema fornisce anche un feedback che avviene una volta al giorno, quando ci sincronizziamo durante le riunioni. Avere un piano comune, strutturato e completamente aperto, consente a tutti di essere a conoscenza di ciò che sta accadendo e di quanto abbiamo fatto fino ad oggi.
Vantaggi della visualizzazione delle attività:
- Causalità. Ogni attività porta a un obiettivo globale. Le attività sono raggruppate in obiettivi più piccoli. Il dominio dell'infrastruttura è piuttosto tecnico. Non è sempre chiaro quale impatto specifico abbia sull'azienda, ad esempio, la scrittura di un runbook per la migrazione su un altro nginx. Avere vicino una scheda obiettivo rende questo più comprensibile.

La causalità è una proprietà importante delle attività. Risponde direttamente alla domanda: «Stò facendo la cosa giusta?» - Paralleli. Siamo nove persone e non è fisicamente possibile che tutti si occupino di un singolo compito. Non sempre ci sono abbastanza compiti in un unico settore. Siamo costretti a svolgere il lavoro in parallelo tra piccoli gruppi di lavoro. In questo modo, i gruppi si concentrano su un compito per un certo periodo di tempo, e possono essere rinforzati da qualcun altro. A volte alcune persone lasciano il gruppo di lavoro. Qualcuno va in vacanza, qualcuno presenta un report per la conferenza DevOps conf, qualcun altro scrive un articolo su Habr. È molto importante sapere quali obiettivi e compiti possono essere svolti in parallelo.
2. Leader sostituibili per le riunioni mattutine. Nei nostri stand-up è emerso un problema: molte persone stanno svolgendo compiti in parallelo. A volte i compiti sono poco correlati e non c'è chiarezza su chi stia facendo cosa. L'opinione di un altro membro del team è molto importante. Questa è un'informazione supplementare che può cambiare l'andamento della risoluzione del compito. Certo, di solito c'è qualcuno con cui lavorare in coppia, ma consultazioni e suggerimenti non sono mai superflui.
Per migliorare questa situazione, abbiamo applicato la tecnica della "Rotazione del facilitatore di standup". Ora ruotano secondo un elenco specifico, e questo ha il suo effetto. Quando arriva il tuo turno, sei costretto a immergerti e capire cosa sta succedendo, per condurre bene la riunione di scrumming.

3. Demo interna. L'assistenza nella risoluzione dei problemi tramite programmazione in coppia, la visualizzazione su un albero delle attività e l'aiuto durante le riunioni di scrumming al mattino sono utili, ma non ideali. In coppia sei limitato solo dalle tue conoscenze. L'albero delle attività aiuta a comprendere globalmente chi fa cosa. E il facilitatore e i colleghi durante la riunione mattutina non si immergeranno profondamente nei tuoi problemi. Possono sicuramente trascurare qualcosa.
La soluzione è stata trovata mostrando i lavori svolti l'uno all'altro e discutendoli successivamente. Ci incontriamo una volta alla settimana per un'ora e mostriamo i dettagli delle soluzioni sui compiti svolti nell'ultima settimana.
Durante la dimostrazione è necessario rivelare i dettagli dell'attività e dimostrarne assolutamente il funzionamento.
Il resoconto può essere fatto seguendo un checklist.1. Introduci il contesto. Da dove è emersa l'attività, perché era necessaria?
2. Come veniva risolta la questione prima? Ad esempio, era necessario effettuare clic massivi con il mouse, oppure era impossibile fare qualcosa.
3. Come miglioriamo questo. Ad esempio: «Guarda, ora c'è uno script, ecco il README».
4. Mostra come funziona. Sarebbe ideale eseguire un qualche scenario utente. Voglio X, faccio Y, vedo Z (o Y). Per esempio, distribuisco NGINX, controllo l'url, ottengo 200 OK. Se l'azione richiede tempo, preparati prima per poterlo dimostrare. È consigliabile non rompere nulla, soprattutto se fragile, un'ora prima della demo.
5. Spiega quanto bene è stata risolta la problema, quali difficoltà sono rimaste, cosa non è stato completato, quali miglioramenti sono possibili in futuro. Ad esempio, ora abbiamo il CLI, in seguito ci sarà una completa automazione in CI.
Ogni relatore dovrebbe rimanere entro i 5-10 minuti. Se la tua presentazione è particolarmente importante e richiederà più tempo, accordati in anticipo nel canale sre-takeover.
Dopo la parte dal vivo, ci sarà necessariamente una discussione nel thread. Qui emerge il feedback necessario sulle proprie attività.

Alla fine viene condotto un sondaggio per valutare l'utilità di quanto sta accadendo. Questa è già una retroazione riguardo l'essenza della presentazione e l'importanza del compito.

Conclusioni lunghe e cosa fare dopo
Potrebbe sembrare che il tono dell'articolo sia piuttosto pessimista. Non è così. Due livelli di base per ottenere feedback, ovvero i test e la programmazione in coppia, stanno funzionando. Non così perfettamente come nello sviluppo tradizionale, ma c'è un effetto positivo.
I test, nella loro forma attuale, offrono solo una copertura parziale del codice. Molte funzionalità di configurazione risultano non testate. Il loro impatto sull'operatività nel momento della scrittura del codice è basso. Tuttavia, c'è un effetto positivo dai test di integrazione, che permettono di effettuare refactoring senza timori. Questo è un grande risultato. Con il trasferimento del focus verso lo sviluppo in linguaggi di alto livello (noi usiamo Python, Go), il problema si attenua. Inoltre, per le verifiche 'collanti', ce ne sono molte e non è necessario, basta la verifica generale di integrazione.
Il lavoro di coppia dipende molto dalle persone specifiche coinvolte. Ci sono fattori relativi al compito e alle nostre soft skills. A volte si riesce a collaborare molto bene, altre volte meno. Di sicuro c'è un vantaggio. È chiaro che, anche considerando il rispetto insufficiente delle regole del lavoro di coppia, il semplice fatto di lavorare insieme ha un'influenza positiva sulla qualità del risultato. Personalmente, trovo più facile e piacevole lavorare in coppia.
Metodi di intervento più avanzati sul sistema operativo – pianificazione e gestione dei compiti portano effettivamente a risultati: uno scambio di conoscenze di alta qualità e un miglioramento nella qualità dello sviluppo.
Conclusioni brevi in una sola riga
- Le pratiche XP funzionano in IaC, ma con un'efficacia inferiore.
- Rafforzate ciò che funziona.
- Inventate i vostri meccanismi e pratiche compensativi.
Fonte: habr.com



