git clone --filter=blob:none --sparse https://github.com/calmict/book_labs.git cd book_labs git sparse-checkout set ansible/ed1
Il manuale si apre con una promessa: diventare il direttore d'orchestra della tua infrastruttura. Ma prima di alzare la bacchetta bisogna capire *perché* lo spartito scritto a mano — lo script Bash — si sbriciola quando i musicisti non sono tre ma tremila. In questo primo laboratorio non useremo ancora Ansible: lo installeremo al capitolo 6. Qui proverai con le tue mani il *problema* che Ansible esiste per risolvere, così che tutto il resto del manuale abbia un senso.
Tre "server" (tre container), uno stato che vuoi mantenere identico su tutti, e uno script che prova a imporlo. Lo script funzionerà. Poi lo rieseguirai, e si aprirà la prima crepa.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap01/solution ./run.sh
Il direttore d'orchestra non impianta un chip nel cervello di ogni musicista: parla, e loro — che già sanno leggere la musica — eseguono. Ansible funziona così. Non installa un *agente* che vive sulla macchina: la visita via SSH, le fa fare una cosa usando il Python che è già lì, e se ne va. Questo si chiama
In questo laboratorio diventi tu il messaggero: rifarai a mano, via SSH, il viaggio che Ansible automatizza per ogni task. Non useremo ancora Ansible (lo installi al capitolo 6): lo scopo è proprio dimostrare che sul target non serve *niente di suo* — solo SSH e Python.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap02/solution ./run.sh
Al capitolo 2 lo script ti ha regalato una chiave e sei entrato sul managed node *tutto* Ansible. Il cuore è la crittografia asimmetrica e una regola d'oro: la chiave privata non lascia mai il control node; viaggia solo la sua metà
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap03/solution ./run.sh
YAML è lo spartito su cui scriverai ogni playbook e ogni inventario. Sembra banale — ed è proprio questa la trappola: un valore scritto come lo pensi può essere diventa 1350. In questo laboratorio impari l'anatomia di YAML e, soprattutto, a non farti mentire dallo spartito. Nessun container, niente Ansible ancora: solo file YAML e lo stesso parser che Ansible usa sotto il cofano (PyYAML).
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap04/solution ./run.sh
Al capitolo 1 hai visto la differenza tra "rilanciabile" e "convergente". Ora la portiamo al cuore: l'idempotenza. Un interruttore della luce è idempotente — lo porti su ON; se è già ON, non succede nulla, e la stanza è comunque illuminata. Un campanello no: ogni pressione suona di nuovo. Ansible è fatto di interruttori: gli dici lo *stato* voluto, lui agisce solo se serve, e ti dice di che colore è stato il cambiamento. Prima di installarlo (capitolo 6), lo costruisci in piccolo con le tue mani: un mini-motore idempotente in bash che riporta i colori e sa fare la "prova a vuoto".
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap05/solution ./run.sh
Per cinque capitoli hai studiato la partitura senza mai alzare la bacchetta. Adesso la prendi in mano: installi Ansible. Ma da bravo direttore non sporchi il palco — lo installi in un ambiente isolato (un virtualenv), così non tocchi il Python di sistema. Poi accordi i musicisti: prepari i nodi che dai prossimi capitoli configurerai.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap06/solution ./run.sh
Il direttore ha la bacchetta (capitolo 6); ora serve il regolamento d'orchestra: ansible.cfg, il file dove vivono le regole di come Ansible lavora — quanti musicisti in parallelo, con che chiave entrare, se chiedere il permesso. La cosa più importante da capire non è *cosa* c'è scritto, ma quale copia del regolamento viene letta: Ansible guarda quattro leggii in ordine fisso e usa il primo che trova, per intero — niente fusioni. E c'è una trappola di sicurezza: se il leggio è in una stanza dove chiunque può scriverci, Ansible si rifiuta di leggerlo.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap07/solution ./run.sh
Il direttore ha bacchetta (cap. 6) e regolamento (cap. 7), ma non sa ancora chi sono i musicisti. L'inventario è la rubrica: i nomi degli host, i loro indirizzi, i gruppi in cui suonano. È il file che trasforma "un container sulla porta 2281" in web1, e "web1 e web2" in web — così da qui in poi dirai *ansible web* e non un elenco di IP. In questo laboratorio la scrivi in INI, la verifichi con gli attrezzi giusti, e alla fine il direttore chiama l'appello:
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap08/solution ./run.sh
La rubrica risponde all'appello (cap. 8). Ora il direttore dà i primi ordini — ma senza scrivere lo spartito completo (quello è il playbook, cap. 10). Un comando per una cosa al volo (chi è acceso? quanto spazio disco? riavvia quel servizio); sbagliato per qualcosa da ripetere o versionare — lì serve lo spartito. Qui impari l'anatomia del cenno, l'arsenale dei moduli, e la differenza cruciale — che già intuivi dal cap. 5 — fra un modulo interruttore e un comando campanello.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap09/solution ./run.sh
Al capitolo 9 il direttore dava cenni al volo: un modulo, un bersaglio, subito. Utili, ma effimeri — nessuna traccia, niente da rivedere, niente da rieseguire con fiducia. Ora scrivi la partitura: il playbook, un file YAML che mette gli stessi moduli in ordine, con un nome, sotto controllo di versione. Questo è il cuore di Ansible — da qui in poi quasi tutto è un playbook. Impari la struttura a strati (play → task → modulo), scrivi il tuo primo playbook riga per riga, impari a leggerne l'output, e riscopri la proprietà più importante di tutte: rieseguirlo non fa danni (la prova del nove del cap. 5, ora su scala).
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap10/solution ./run.sh
Al capitolo 10 il privilegio era un interruttore acceso in blocco: become: true, e tutto girava da root. Ora apri quella scatola. become non è "diventa root e basta": è chiedere le chiavi al custode dell'edificio — su Linux, quasi sempre sudo. Il custode ha un regolamento (il file sudoers): decide *chi* può prendere *quale* chiave, e se prima deve mostrare un documento (la password). Questo capitolo — il primo della fascia Intermedio — ti fa vedere l'anatomia di become, il regolamento sotto il cofano, le tre risposte alla password, come diventare un utente *diverso* da root, e le regole d'oro per non lasciare in giro la chiave universale.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap11/solution ./run.sh
Lo spartito del capitolo 10 era rigido: /etc/motd, porta 80, quei valori scritti dentro il playbook. Ma web1 e web2 non sono identici — porte diverse, limiti diversi — e riscrivere il playbook per ciascuno sarebbe la crepa del capitolo 1 che ritorna. Le scritto una volta e riusato ovunque, che può arrivare da tante fonti — il gruppo, il singolo host, la riga di comando, i fatti che Ansible scopre da solo. In questo capitolo vedi che forma hanno (i tipi), come si usano (le doppie graffe di Jinja2), dove vivono, come catturare al volo un risultato, e come tenerle in ordine.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap12/solution ./run.sh
Al capitolo 12 hai visto la riga di comando battere il group_vars, quasi senza pensarci. Non era magia: era precedenza. Ansible ti lascia definire una variabile in *tanti* posti — comodità enorme — ma il prezzo è che, quando due posti dichiarano lo stesso nome con valori diversi, qualcuno deve vincere. Ansible ha una catena di comando rigida: non ti fa costruire infrastruttura: ti fa *indagare*. Provochi scontri reali fra variabili, guardi chi vince, impari i tre principi che spiegano quasi tutto, i due trabocchetti che sorprendono tutti, e come progettare per non litigare mai.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap13/solution ./run.sh
Cambi la configurazione di un servizio: ora va ricaricato perché la rilegga. Ma ricaricarlo a *ogni* esecuzione del playbook — anche quando non hai toccato nulla — è spreco e rischio: interruzioni inutili, connessioni cadute, per niente. Vuoi ricaricarlo handler: un task lascia un *richiamo*, e a fine prova — solo se quel task ha riportato changed — l'handler scatta. È il colore changed del capitolo 5 che smette di essere un semplice segnale e diventa un innesco**.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap14/solution ./run.sh
Finora ogni task faceva una cosa, una volta, sempre. Ma la realtà si adatta: dev e prod non sono uguali, certe feature sono opzionali, certe azioni vanno ripetute su venti elementi. Servono due nuovi poteri. when dà al task la capacità di *decidere*: agisci solo *se* una condizione è vera. loop gli dà quella di *ripetere*: un solo task, molti elementi. Con questi due — e con la trappola delle graffe che li accompagna — un playbook smette di essere una lista fissa e diventa una procedura intelligente.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap15/solution ./run.sh
Il playbook del capitolo 15 sa decidere e ripetere — ma è cresciuto: task, variabili, template, handler, tutto ammucchiato in un file solo. Domani un secondo progetto vorrà la stessa app: copi e incolli? Il ruolo è la risposta. È una sezione dell'orchestra: un blocco autonomo, con dentro i suoi task, i suoi file, la sua accordatura predefinita, che il direttore richiama con un nome — e che puoi riusare in qualsiasi concerto. In questo capitolo trasformi quel playbook gonfio in un ruolo pulito, e il playbook torna a essere tre righe.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap16/solution ./run.sh
Il ruolo del capitolo 16 è tuo, scritto in casa. Ma migliaia di persone hanno già scritto e condiviso ruoli e moduli per ogni compito immaginabile: gestire firewall, database, provider cloud, servizi di sistema. Non devi ricomporre ciò che esiste già — puoi attingere al l'FQCN. Questo capitolo — l'ultimo della fascia Intermedio — ti insegna a stare sulle spalle dei giganti senza perdere la riproducibilità.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap17/solution ./run.sh
Al capitolo 11 hai chiesto le chiavi al custode: become, e per il nodo con sudo a password l'hai fatto funzionare — ma la password l'hai scritta *in chiaro* nell'inventario, con la promessa "un giorno la cifreremo". Quel giorno è oggi. Un playbook finisce in un repository Git, e Git *non dimentica*: una password committata in chiaro resta nella cronologia per sempre, anche se la cancelli domani. Questo capitolo — il primo della fascia Avanzato — apre la cassaforte di Ansible: Ansible Vault, che cifra i segreti *dentro* i tuoi file, così che il repository resti condivisibile e il segreto resti segreto.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap18/solution ./run.sh
Al capitolo 18 hai chiuso la password in cassaforte. Ma alla fine restava un paradosso: la cassaforte è cifrata, e la sua chiave — la parola d'ordine del vault — dove vive? Se la scrivi in un file accanto al playbook, sei tornato al peccato del capitolo 11: un segreto in chiaro su disco. Il capitolo 18 ha spostato il problema, non l'ha eliminato. La soluzione vera cambia paradigma: il segreto non si conserva affatto — né in chiaro né cifrato — ma si va a prendere a runtime da un servizio esterno che lo custodisce, lo consegna a chi ha diritto, e non lascia mai che riposi con te. Quel servizio è un caveau: in questo laboratorio, HashiCorp Vault.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap19/solution ./run.sh
Finora hai *passato* i dati: una variabile qui, una lista lì, un dizionario in un template. Ma i dati grezzi raramente hanno già la forma che ti serve: hai un elenco di servizi e ne vuoi solo quelli attivi; hai una configurazione di base e un pacchetto di modifiche per l'ambiente, e li vuoi fusi; hai una mappa e la vuoi scorrere riga per riga. Il capitolo 20 ti dà l'arrangiatore: Jinja2 nella sua forma piena — i filtri che trasformano, i test che interrogano, i lookup che pescano — e i template .j2 che, dai dati, scrivono la configurazione *da soli*. Smetti di scrivere config a mano: la config diventa una *funzione* dei dati.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap20/solution ./run.sh
Al capitolo 8 hai scritto la rubrica a mano: un file con i nodi, uno per riga. Funziona finché la flotta sta ferma. Ma nel mondo reale la flotta *si muove da sola*: macchine che nascono quando il carico sale e muoiono quando scende, nel cloud, mentre tu dormi. Una rubrica scritta a mano è vecchia nel momento in cui la salvi. La risposta è ribaltare il meccanismo: invece di *elencare* i nodi, li fai presentare all'appello — Ansible chiede a chi la flotta la conosce davvero (il provider) "chi c'è adesso?", e costruisce l'inventario *sul momento*. Qui il provider è il demone Docker, e la flotta sono container che vanno e vengono; ma AWS, Azure, GCP funzionano identici.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap21/solution ./run.sh
Sai scoprire la flotta (cap. 21) e agirci sopra. Ma un'orchestra vera suona in un mondo imperfetto: una corda salta a metà concerto, un leggio cade, un musicista sbaglia l'attacco. La domanda non è *se* qualcosa andrà storto su uno dei mille nodi dell'appello, ma *cosa fa il direttore quando succede*. Di default Ansible, davanti a un errore, si ferma su quell'host — prudente, ma non basta. Questo capitolo ti dà gli strumenti della resilienza: recuperare con block/rescue/always, riprovare ciò che è lento, ridefinire cosa conta come errore, e — quando serve — fermare tutto in fretta prima che il disastro si propaghi.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap22/solution ./run.sh
Il capitolo 22 ti ha insegnato a *reagire* agli errori. Ma il modo migliore di gestire un errore è non commetterlo — o almeno scoprirlo *prima* di toccare la produzione. Prima di un concerto nessuna orchestra sale sul palco alla cieca: rilegge le parti (c'è un errore di stampa?), fa la prova generale a teatro vuoto (suona tutto, senza pubblico), e solo allora apre le porte. Ansible ti dà la stessa rete di sicurezza, a tre livelli sempre più ricchi: --syntax-check (la lettura veloce), ansible-lint (il revisore esperto), e il check mode con --diff (la prova generale che ti mostra cosa cambierebbe senza cambiarlo). Meglio un errore rosso sul tuo terminale che un guasto silenzioso su mille nodi.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap23/solution ./run.sh
Il capitolo 23 ti ha dato tre reti — syntax-check, lint, check mode — ma nessuna delle tre *esegue* davvero il ruolo su un sistema vero. Un lint pulito e una prova a teatro vuoto dicono che il playbook è *ben scritto* e cosa *cambierebbe*, non che il ruolo funziona: che parte da zero, converge, è idempotente, e lascia il sistema nello stato giusto. Questo è il muro che il capitolo 23 non supera. Molecule lo abbatte: monta un ambiente vero ma usa-e-getta (un container), applica il ruolo, verifica idempotenza e risultato, e smonta tutto — un comando su, un comando giù. È la prova sul palco vero, con la certezza di poterlo sempre ricostruire da capo.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap24/solution ./run.sh
Finora hai orchestrato pochi nodi, e a pochi nodi ogni playbook sembra veloce. Ma la fascia Cloud Architect comincia da una domanda diversa: cosa succede quando i nodi diventano mille? A quella scala un secondo di troppo per host non è un secondo — è un'attesa che non finisce, moltiplicata per mille, ripetuta a ogni deploy. Il collo di bottiglia non è più *cosa* fa il playbook, ma *come* Ansible lo distribuisce sulla flotta. Questo capitolo ti dà le leve per stringere quel tempo: quanti nodi guidare insieme (forks), se farli marciare in lock-step o lasciarli correre (strategie), e come non pagare lavoro che non serve (domare i fatti). Le misuri su una flotta vera — dodici nodi — e le vedi mordere: la stessa consegna passa da ~24 secondi a ~8.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap25/solution ./run.sh
Il capitolo 25 ti ha dato la velocità per servire mille nodi. Ma a questa scala una cosa è già cambiata sotto i tuoi piedi: non è più una persona a lanciare il playbook. Con mille nodi e più mani sullo stesso codice, un ansible-playbook battuto a mano dal portatile di qualcuno è troppo fragile — nessuno ha controllato il lint, nessuno sa da quale versione parte, nessuno impedisce che una modifica non provata finisca in produzione un venerdì sera. La risposta è una macchina di scena: ogni modifica passa dal controllo di versione, attraversa una pipeline che la valida da sola (CI), e solo una release autorizzata attraversa il cancello ed entra in produzione (CD). Questo capitolo la costruisce: i cancelli di qualità su GitHub Actions, il cancello di produzione che si apre solo su un tag, e i pre-commit hook che anticipano il controllo prima ancora del commit.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap26/solution ./run.sh
Il capitolo 26 ti ha dato la macchina di scena che porta una modifica fino alla porta della produzione. Ma il job di deploy era una riga di echo, e ora arriva la domanda vera: *come* si aggiorna una flotta di mille nodi senza spegnere il servizio? Applicare a tutti insieme è un disservizio — per qualche secondo o minuto, ogni backend è giù nello stesso momento. Un direttore d'orchestra non ferma tutta l'orchestra per far cambiare l'arco a un violinista: fa entrare e uscire le sezioni una alla volta, e la musica non si interrompe mai. Questo è l'orchestrazione: il rolling update. Questo capitolo ti dà le leve — serial (aggiorna a ondate), delegate_to (di' al bilanciatore di togliere il nodo dal giro prima di toccarlo), la coreografia pre_tasks/tasks/post_tasks (drena → aggiorna → ri-abilita), e max_fail_percentage (il freno d'emergenza che ferma tutto se un'ondata va male) — e le vedi all'opera su una web-farm dove, in ogni istante, non più di un'ondata è fuori dal giro.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap27/solution ./run.sh
Il capitolo 27 ti ha dato il rilascio a ondate; il 26 la pipeline che lo lancia. Ma in tutti e due sei ancora tu — o uno script — a battere un comando da un terminale, con inventari, credenziali e "chi-può-fare-cosa" tenuti in testa o sparsi in file. Funziona per una persona. Non funziona per un'organizzazione: dieci team, centinaia di playbook, migliaia di nodi, revisori e audit. A quel punto il terminale non basta più — come una compagnia che gira di piazza in piazza non basta più quando la città vuole una stagione stabile, con una sede, un botteghino, un organico e un archivio. l'automazione smette di essere un gesto al terminale e diventa un servizio con una console, i suoi permessi e la sua storia. Questo capitolo ne monta gli oggetti fondamentali — il job template, le versionati e validati prima di entrare in scena. Perché il modo Cloud Architect di gestire la piattaforma non è "clicca nella UI": è GitOps anche qui.
Completa i TODO nei file di partenza, poi lancia il test della soluzione:
cd ansible/ed1/cap28/solution ./run.sh