Ciao, Habr! In passato mi sono lamentato della vita nella paradigma dell'Infrastructure as code e non ho proposto soluzioni per la situazione attuale. Oggi sono tornato per raccontare quali approcci e pratiche possono aiutare a uscire dall'abisso della disperazione e a indirizzare la situazione nel verso giusto.

Nell'articolo precedente Ho condiviso le mie impressioni su quest'area, ho tentato di riflettere sulla situazione attuale in questo campo e ho anche ipotizzato che le pratiche standard, conosciute a tutti gli sviluppatori, possono essere d'aiuto. Potrebbe sembrare che ci siano state molte lamentele sulla vita, ma poche proposte per uscire dalla situazione attuale.
Chi siamo, dove siamo e quali sono i nostri problemi
Al momento siamo nel Sre Onboarding Team, composto da sei programmatori e tre ingegneri di infrastruttura. Tutti noi cerchiamo di scrivere Infrastructure as code (IaC). Lo facciamo perché, in linea di massima, sappiamo scrivere codice e nel nostro percorso abbiamo già avuto esperienza come sviluppatori di livello 'superiore alla media'.
- Abbiamo un insieme di vantaggi: un certo background, conoscenza delle pratiche, capacità di scrivere codice e voglia di imparare cose nuove.
- E ci sono dei punti deboli, o svantaggi: mancanza di conoscenze sui fondamenti dell'infrastruttura.
Il stack tecnologico che utilizziamo nel nostro IaC.
- Terraform per la creazione delle risorse.
- Packer per la creazione delle immagini. Queste sono immagini Windows e CentOS 7.
- Jsonnet, per creare potenti configurazioni in drone.io, oltre per generare packer json e i nostri moduli Terraform.
- Azure.
- Ansible per la preparazione delle immagini.
- Python per i servizi ausiliari e per gli script di provisioning.
- E tutto questo in VSCode con i plugin condivisi tra i membri del team.
La mia conclusione è stata: cercavo di infondere (prima di tutto in me stesso) ottimismo, volevo dire che proveremo approcci e pratiche a noi noti per affrontare le difficoltà e le complessità di questo campo. Attualmente stiamo affrontando i seguenti problemi dell'IaC:
Imperfezione degli strumenti e dei mezzi per lo sviluppo del codice.
- Distribuzione lenta. L'infrastruttura è una parte del mondo reale, e questo può non essere veloce.
- Mancanza di approcci e pratiche.
- Siamo nuovi e non sappiamo molto.
- La programmazione estrema (XP) è pronta a darci una mano.
La programmazione estrema (XP) è pronta a darci una mano.
A tutti gli sviluppatori è familiare il programming estremo (XP) e le pratiche ad esso associate. Molti di noi hanno lavorato secondo questo approccio e si è rivelato efficace. Allora perché non sfruttare i principi e le pratiche che vi sono alla base per superare 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 per cui XP è particolarmente adatto e come si rapporta a noi:
1. Requisiti software che cambiano dinamicamente. Avevamo chiara quale fosse l'obiettivo finale. Ma nei dettagli si possono variare. Siamo noi a decidere dove dobbiamo indirizzarci, quindi i requisiti cambiano periodicamente (principalmente da noi stessi). Se consideriamo il team SRE, che fa automazione e al tempo stesso definisce i requisiti e l'ambito del lavoro, questo punto si adatta bene.
2. Rischi causati da progetti a tempo fisso che utilizzano nuove tecnologie. Possiamo incontrare rischi nell'uso di alcune tecnologie a noi sconosciute. E questo è il nostro caso al 100%. L'intero nostro progetto si basa su tecnologie con cui non eravamo completamente a nostro agio. Questo è un problema costante, poiché nel campo dell'infrastruttura emergono continuamente nuove tecnologie.
3,4. Piccolo team di sviluppo collocato e ampliato. La tecnologia che stai utilizzando consente test unitari e funzionali automatizzati. Questi due punti non si adattano completamente a noi. In primo luogo, non siamo un team collocato, in secondo luogo, siamo nove persone, il che può essere considerato un grande team. Anche se, secondo alcune definizioni, un grande team è composto da 14 o più persone.
Esaminiamo alcune pratiche di XP e come influenzano la velocità e la qualità del feedback.
Principio del ciclo di feedback in XP
Per me, il feedback è la risposta alla domanda se stiamo facendo le cose nel modo giusto e se stiamo andando nella giusta direzione. In XP ci sono schemi straordinari: il ciclo di feedback nel tempo. L'aspetto interessante è che più siamo in basso, più rapidamente possiamo ricevere il feedback operativo per rispondere alle domande necessarie.

È un argomento piuttosto interessante da discutere, poiché nella nostra industria IT è possibile ottenere rapidamente feedback operativo. Immagina quanto possa essere doloroso e difficile lavorare a un progetto per sei mesi e solo dopo scoprire che all'inizio era stato commesso un errore. Questo può accadere sia nella progettazione sia nella costruzione 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 è basato su cicli mensili, ma avviene più volte al giorno. A questo ciclo sono legate alcune pratiche che esamineremo più in dettaglio.
Importante: il feedback può risolvere tutti i problemi citati sopra. Combinato con le pratiche XP, può tirarti fuori dal baratro della disperazione.
Come tirarsi fuori dal baratro della disperazione: tre pratiche
Test
I test vengono menzionati due volte nel ciclo di feedback XP. Non è affatto casuale. Sono estremamente importanti per tutta la tecnica della programmazione estrema.
Si presume che tu abbia test Unit e di Accettazione. I primi ti danno feedback in pochi minuti, i secondi in qualche giorno, perciò scriverli richiede più tempo, ma vengono eseguiti meno frequentemente.
C'è una classica piramide dei test che mostra che ci devono essere più test di quel tipo.

Come si applica questo schema al nostro progetto IaC? In realtà... non si applica affatto.
- Non possono esserci troppi test Unit, anche se dovrebbero essercene molti. O testano qualcosa in modo molto indiretto. Di fatto, possiamo dire che non li scriviamo affatto. Ma ecco alcune applicazioni per tali test che siamo riusciti comunque a realizzare:
- Test del codice su jsonnet. Questo è, ad esempio, il nostro pipeline di build in drone, che è piuttosto complesso. Il codice in jsonnet è ben coperto dai test.
Utilizziamo questo . - Test sugli script che vengono eseguiti all'avvio della risorsa. Gli script sono in Python, quindi possiamo scriverci test.
- Test del codice su jsonnet. Questo è, ad esempio, il nostro pipeline di build in drone, che è piuttosto complesso. Il codice in 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 di configurazione delle risorse tramite . Tuttavia, per Terraform ci sono solo controlli molto basilari, ma sono stati scritti molti scenari di test per AWS. E noi siamo su Azure, quindi di nuovo non va bene.
- Test di integrazione dei componenti: qui dipende da come li classifichi e dove li assegni. Ma in linea di principio funzionano.
Ecco come appaiono i test di integrazione.

Questo è un esempio durante la costruzione delle immagini in Drone CI. Per arrivarci, bisogna aspettare 30 minuti affinché si costruisca l'immagine Packer, poi altri 15 minuti per i test. Ma ci sono!Algoritmo di verifica delle immagini
- Prima Packer deve preparare completamente l'immagine.
- Accanto al test c'è un terraforming con uno stato locale, con cui dispieghiamo questa immagine.
- Durante il dispiegamento viene utilizzato un piccolo modulo, situato nelle vicinanze, per lavorare più facilmente con l'immagine.
- Quando è stata dispiegata una VM dall'immagine, si possono iniziare i controlli. Principalmente, i controlli vengono effettuati sulla macchina. Si verifica come hanno funzionato gli script all'avvio, come operano i demoni. A tal fine, tramite ssh o winrm, accediamo alla macchina appena avviata e controlliamo lo stato della configurazione o se i servizi sono stati avviati.
- Situazione simile con i test di integrazione e nei moduli per Terraform. Ecco una breve tabella che chiarisce le peculiarità di tali test.

Il feedback nel pipeline è di circa 40 minuti. Tutto avviene molto lentamente. Può essere usato per il regresso, ma per un nuovo sviluppo è totalmente irrealizzabile. Se ci si prepara molto, prepara i running e gli script, si può ridurre a 10 minuti. Ma non si tratta comunque di unit test, che possono essere fatti 100 in 5 secondi.
L'assenza di unit test durante la creazione di immagini o moduli 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 alla sua distruzione si cancellasse.
Poiché ScaleFT è per noi un servizio, siamo costretti a lavorare con esso tramite API. Qui è stata scritta una wrapper, che può essere chiamata per dire: "Vai e cancella questo e quello". Essa conserva tutte le configurazioni e gli accessi necessari.
Su questo possiamo già scrivere test normali, poiché non si differenzia affatto dal software normale: viene mockato qualche API, lo chiami e vediamo cosa succede.

Risultati dei test: il test unitario, che dovrebbe fornire il sistema operativo in un minuto, non lo fa. E tipi di test di livello superiore nella piramide danno effetti, ma coprono solo una parte dei problemi.
Programmazione a coppie
I test sono, naturalmente, utili. Possono essere scritti in gran quantità e possono assumere forme diverse. Funzioneranno ai loro livelli e forniranno feedback. Tuttavia, il problema dei test unitari scadenti, che offrono il sistema operativo più veloce, rimane. Eppure si continua a desiderare un sistema operativo veloce, con il quale sia facile e piacevole lavorare. Senza contare la qualità della soluzione ottenuta. Fortunatamente, ci sono tecniche che consentono di fornire un feedback ancora più veloce rispetto ai test modulari. Questo è il pair programming.
Quando si scrive codice, si desidera ricevere feedback sulla sua qualità il più velocemente possibile. Sì, è possibile scrivere tutto in un branch di funzionalità (per non rompere nulla a nessuno), fare una pull request su GitHub, assegnarla a qualcuno il cui parere conta, e aspettare una risposta.
Ma si può aspettare a lungo. Le persone sono tutte occupate e una risposta, anche se arriva, potrebbe non essere della massima qualità. Supponiamo che la risposta arrivi subito, il revisore capisca immediatamente l'intera idea, ma la risposta comunque arriva con un ritardo, a posteriori. E si vorrebbe riceverla prima. Ecco perché il pair programming è mirato a questo: per ricevere feedback immediato, mentre si scrive.
Di seguito vengono presentati gli stili di pair programming e la loro applicabilità nel lavoro su IaC:
1. Classico, Esperto + esperto, cambio al timer. Due ruoli: driver e navigator. Due persone. Lavorano su un unico codice e cambiano ruolo dopo un intervallo di tempo prestabilito.
Consideriamo la compatibilità dei nostri problemi con lo stile:
- Problema: imperfezione degli strumenti e dei mezzi per lo sviluppo del codice.
Impatto negativo: sviluppiamo più a lungo, ci rallentiamo, perdiamo il ritmo di lavoro.
Come affrontiamo il problema: utilizziamo strumenti diversi, un IDE condiviso e apprendiamo anche le scorciatoie. - Problema: distribuzione lenta.
Impatto negativo: aumenta il tempo per creare un pezzo di codice funzionante. Ci annoiamo mentre aspettiamo, le mani si allungano per fare qualcos'altro mentre aspetti.
Come affrontiamo il problema: non abbiamo trovato una soluzione. - Problema: mancanza di approcci e pratiche.
Impatto negativo: non c'è conoscenza su come fare bene e come fare male. Allunga il tempo per ricevere feedback.
Come affrontiamo il problema: lo scambio di opinioni e pratiche nel lavoro in coppia risolve quasi completamente il problema.
Il principale problema nell'applicazione di questo stile in IaC è il ritmo di lavoro irregolare. Nello sviluppo software tradizionale hai un movimento molto uniforme. Puoi impiegare cinque minuti e scrivere N. Impiegare dieci minuti e scrivere 2N, quindici minuti – 3N. Qui, invece, puoi impiegare cinque minuti e scrivere N, e poi impiegare altri trenta minuti e scrivere un decimo di N. Qui non sai niente, hai un blocco, un'impasse. L'analisi richiede tempo e distrae dalla programmazione diretta.
Conclusione: in forma pura non ci adatta.
2. Ping-pong. Questo approccio prevede che un partecipante scriva un test, mentre l'altro ne realizza l'implementazione. Considerando che con i test unitari è tutto complicato, e che è necessario scrivere un lungo test di integrazione, tutta la leggerezza del ping-pong svanisce.
Posso dire che abbiamo provato a separare le responsabilità per la progettazione dello scenario di test e l'implementazione del codice per esso. Un partecipante ha ideato lo scenario, in questo aspetto del lavoro era responsabile, aveva l'ultima parola. L'altro era responsabile per l'implementazione. Questo funzionava bene. La qualità dello scenario con questo approccio aumenta.
Conclusione: ahimè, 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 direttivo, mentre l'altro assume il ruolo di driver esecutivo. In questo caso, il diritto delle decisioni spetta esclusivamente al navigatore. Il driver si limita a digitare e può influenzare ciò che accade con le parole. I ruoli non cambiano per lungo tempo.
È molto adatto per l'apprendimento, ma richiede forti soft skills. Su questo ci siamo inceppati. La tecnica si è rivelata difficile. E non si tratta nemmeno dell'infrastruttura.
Conclusione: potenzialmente può essere applicato, non abbandoniamo i tentativi.
4. Mobbing, swarming e tutti gli stili noti ma non elencati qui. non vengono considerati, poiché non abbiamo provato e non possiamo dire nulla in relazione al nostro lavoro.
Risultati generali sull'uso della programmazione in coppia:
- Abbiamo un ritmo di lavoro irregolare che crea confusione.
- Ci siamo scontrati con soft skills non sufficientemente buone. E l'area tematica non aiuta a superare queste nostre carenze.
- Test lunghi e problemi con gli strumenti rendono lo sviluppo in coppia faticoso.
5. Nonostante ciò, ci sono stati anche dei successi. Abbiamo ideato il nostro metodo "Convergenza - Divergenza". Brevemente spiegherò come funziona.
Abbiamo partner permanenti per alcuni giorni (meno di una settimana). Facciamo un compito insieme. Per un certo periodo stiamo insieme: uno scrive, l'altro osserva come un team di supporto. Poi ci separiamo per un po', ognuno si occupa di cose indipendenti, poi ci ritroviamo, ci sincronizziamo molto rapidamente, facciamo qualcosa insieme e ci separiamo di nuovo.
Pianificazione e comunicazione
L'ultimo blocco di pratiche per risolvere i problemi del sistema operativo è l'organizzazione del lavoro con le stesse attività. Qui rientra anche lo scambio di esperienze che si svolge al di fuori del lavoro in coppia. Consideriamo tre pratiche:
1. Attività tramite albero degli obiettivi. Per la gestione generale del progetto abbiamo organizzato un albero che si estende all'infinito nel futuro. Tecnicalmente, la gestione avviene in Miro. C'è un'attività - è un obiettivo intermedio. Da essa partono obiettivi più piccoli o gruppi di attività. Da loro, ci sono già 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 nelle riunioni. Avere un piano comune visibile a tutti, strutturato e completamente aperto, permette a ciascuno di essere aggiornato su ciò che accade e su quanto siamo progrediti.
Vantaggi della visione visiva delle attività:
- Causalità. Ogni attività porta a un obiettivo globale. Le attività sono raggruppate per obiettivi più piccoli. Il dominio delle infrastrutture è di per sé abbastanza tecnico. Non è sempre immediatamente chiaro quale impatto abbia sul business, ad esempio, la scrittura di un runbook per la migrazione su un altro nginx. Avere accanto una scheda obiettivo rende tutto più chiaro.

La causalità è una proprietà importante delle attività. Risponde direttamente alla domanda: "Sto facendo la cosa giusta?" - Parallelo. Siamo nove persone, e non è fisicamente possibile che tutti si concentrino su un unico compito. Non sempre ci sono abbastanza compiti in un'unica area. Siamo costretti a parallelizzare il lavoro tra piccoli gruppi di lavoro. In questo modo, i gruppi si dedicano per un certo periodo al proprio compito, e possono essere rinforzati da qualcun altro. Da questo gruppo di lavoro a volte si distaccano persone. Qualcuno va in vacanza, qualcun altro fa una relazione per la conferenza DevOps conf, qualcun altro scrive un articolo su Habr. È molto importante sapere quali obiettivi e compiti possono essere eseguiti in parallelo.
2. Leader alternati per le riunioni del mattino. Nei meeting stand-up è emerso un problema: molte persone svolgono compiti in parallelo. A volte i compiti sono debolmente collegati e non c'è comprensione di cosa stia facendo ciascuno. E l'opinione di un ulteriore membro del team è molto importante. È un'informazione aggiuntiva che può cambiare l'andamento della soluzione del compito. Certamente, di solito c'è qualcuno con te in coppia, ma consulenze e suggerimenti sono sempre utili.
Per migliorare questa situazione, abbiamo applicato la tecnica "Cambio del leader dello stand-up". Ora ruotano secondo un elenco prestabilito, e questo ha un effetto. Quando arriva il tuo turno, sei costretto a immergerti e capire cosa sta succedendo, per condurre bene il meeting scrum.

3. Demo interna. L'assistenza nella risoluzione dei compiti dal pair programming, la visualizzazione nell'albero delle attività e l'aiuto nei meeting scrum del mattino è buona, ma non è ideale. In coppia sei limitato solo alle tue conoscenze. L'albero delle attività aiuta a comprendere globalmente chi fa cosa. E il leader e i colleghi durante l'incontro del mattino non si immergeranno profondamente nei tuoi problemi. Possono sicuramente trascurare qualcosa.
La soluzione è stata trovata nella dimostrazione del lavoro svolto l'uno all'altro e nella successiva discussione. Ci incontriamo una volta alla settimana per un'ora e mostriamo i dettagli delle soluzioni ai compiti che abbiamo realizzato nell'ultima settimana.
Durante la dimostrazione, è necessario rivelare i dettagli del compito e dimostrare obbligatoriamente il suo funzionamento.
La relazione può essere condotta seguendo una lista di controllo.1. Introduciti nel contesto. Da dove è venuto il compito, perché era necessario?
2. Come è stato risolto il compito prima? Ad esempio, era necessario un massiccio clic sul mouse, o era del tutto impossibile fare qualcosa.
3. Come miglioriamo questo. Ad esempio: "Guardate, ora c'è uno script, ecco il readme".
4. Mostratemi come funziona. È preferibile realizzare direttamente uno scenario utente. Voglio X, faccio Y, vedo Й (o Z). Ad esempio, faccio il deploy di NGINX, nella mia url vedo 200 OK. Se l'operazione richiede tempo, preparatela in anticipo in modo da poterla mostrare. È preferibile non rompere nulla un'ora prima della demo, se è fragile.
5. Spiegate quanto bene è stata risolta la questione, quali difficoltà sono rimaste, cosa non è stato completato, quali miglioramenti sono possibili in futuro. Ad esempio, ora c'è la cli, poi ci sarà l'automazione completa nel CI.
È auspicabile che ciascun relatore si attenga ai 5-10 minuti. Se la vostra presentazione è di fondamentale importanza e richiederà più tempo, concordatelo in anticipo nel canale sre-takeover.
Dopo la parte dal vivo segue necessariamente una discussione nel thread. È proprio qui che appare il feedback necessario sui propri compiti.

Alla fine viene condotto un sondaggio per identificare l'utilità di quanto avvenuto. Questo costituisce già un feedback in merito all'essenza della presentazione e all'importanza del compito.

Conclusioni lunghe e quali sono i prossimi passi
Può sembrare che il tono dell'articolo sia piuttosto pessimista. Non è così. I due livelli inferiori di ricezione del feedback, ovvero i test e la programmazione a coppie, funzionano. Non così perfettamente come nella programmazione tradizionale, ma ci sono effetti positivi.
I test, nella loro forma attuale, forniscono solo una copertura parziale del codice. Molte funzioni di configurazione si rivelano non testate. Il loro impatto sul lavoro immediato durante la scrittura del codice è minimo. Tuttavia, gli effetti dei test di integrazione sono evidenti, e proprio questi permettono di effettuare refactoring senza timori. Questo è un grande traguardo. Inoltre, con il cambio di focus verso lo sviluppo in linguaggi ad alto livello (noi usiamo python, go), il problema si riduce. E per il 'collante' ci sono molte verifiche e non è necessario, basta una verifica integrativa generale.
Il lavoro a coppie dipende maggiormente dalle persone specifiche. Ci sono il fattore compito e le nostre soft skills. Con alcuni funziona molto bene, con altri meno. Ma i benefici ci sono di sicuro. È chiaro che anche in caso di rispetto insufficiente delle regole del lavoro a coppie, il semplice fatto di svolgere insieme i compiti influisce positivamente sulla qualità del risultato. Personalmente, lavorare a coppie risulta più facile e piacevole.
Metodi più ad alto livello di influenza sul OS – la pianificazione e il lavoro con i compiti danno sicuramente effetti: uno scambio di conoscenze di qualità e un miglioramento della qualità dello sviluppo.
Conclusioni brevi in una riga
- Le pratiche XP funzionano in IaC, ma con un'efficienza inferiore.
- Rafforza ciò che funziona.
- Inventa i tuoi meccanismi e pratiche compensative.
Fonte: habr.com



