{"id":87084,"date":"2020-07-03T13:42:34","date_gmt":"2020-07-03T11:42:34","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron"},"modified":"2020-07-03T13:42:34","modified_gmt":"2020-07-03T11:42:34","slug":"osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","title":{"rendered":"Le basi di Ansible, senza le quali i vostri playbook saranno un groviglio di spaghetti appiccicati","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Faccio molte revisioni del codice di altri su Ansible e scrivo molto. Analizzando gli errori (sia degli altri che miei) e attraverso un certo numero di colloqui, ho capito un errore fondamentale che commettono gli utenti di Ansible: si avventurano in cose complesse senza aver prima padroneggiato le basi.<\/p>\n<p><\/p>\n<p>Per correggere questa ingiustizia universale, ho deciso di scrivere un'introduzione ad Ansible per coloro che lo conoscono gi\u00e0. Avviso, non \u00e8 un riassunto delle guide, \u00e8 un lungo articolo con molte parole e senza immagini.<\/p>\n<p><\/p>\n<p>Il livello atteso del lettore \u00e8 quello di aver gi\u00e0 scritto diverse migliaia di righe di YAML, di aver gi\u00e0 prodotto qualcosa, ma \"\u00e8 tutto un po' storto\".<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>Nomi<\/h1>\n<p><\/p>\n<p>Il principale errore dell'utente di Ansible \u00e8 non sapere come si chiamano le cose. Se non conosci i nomi, non puoi comprendere ci\u00f2 che \u00e8 scritto nella documentazione. Un esempio concreto: durante un colloquio, una persona, che sembrava aver scritto molto in Ansible, non \u00e8 stata in grado di rispondere alla domanda \"di quali elementi \u00e8 composto un playbook?\". E quando ho suggerito che \"ci si aspettava una risposta secondo cui il playbook \u00e8 composto da play\", \u00e8 seguita una risposta devastante: \"noi non lo usiamo\". Le persone scrivono in Ansible per soldi e non usano i play. <em>In realt\u00e0 li usano, ma non sanno cosa siano.<\/em><\/p>\n<p><\/p>\n<p>Quindi iniziamo con qualcosa di semplice: come si chiamano le cose. Forse lo sapete gi\u00e0, oppure no, perch\u00e9 non ci avete prestato attenzione mentre leggevate la documentazione.<\/p>\n<p><\/p>\n<p>ansible-playbook esegue il playbook. Un playbook \u00e8 un file con estensione yml\/yaml, all'interno del quale c'\u00e8 qualcosa del genere:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n- hosts: group1\n  roles:\n    - role1\n\n- hosts: group2,group3\n  tasks:\n    - debug:<\/code><\/pre>\n<p><\/p>\n<p>Abbiamo gi\u00e0 capito che l'intero file \u00e8 il playbook. Possiamo mostrare dove ci sono i ruoli (roles) e dove ci sono i task (tasks). Ma dove sono i play? E in cosa si differenzia un play da un role o da un playbook?<\/p>\n<p><\/p>\n<p>Tutto questo \u00e8 presente nella documentazione. E lo si trascura. I principianti perch\u00e9 ci sono troppe informazioni e non si pu\u00f2 ricordare tutto subito. Gli esperti perch\u00e9 \"sono cose triviali\". Se sei un esperto, leggi queste pagine almeno una volta ogni sei mesi, e il tuo codice diventer\u00e0 molto migliore.<\/p>\n<p><\/p>\n<p>Quindi, memorizza: il Playbook \u00e8 un elenco composto da play e <code>import_playbook<\/code>.<br \/>\nQuesta \u00e8 una play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group1\n  roles:\n    - role1<\/code><\/pre>\n<p><\/p>\n<p>E anche questa \u00e8 un'altra play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group2,group3\n  tasks:\n    - debug:<\/code><\/pre>\n<p><\/p>\n<p>Cos'\u00e8 allora una play? A cosa serve?<\/p>\n<p><\/p>\n<p>Play \u00e8 un elemento chiave per il playbook, perch\u00e9 il play, e solo il play, collega l'elenco dei ruoli e\/o delle attivit\u00e0 con l'elenco degli host sui quali devono essere eseguiti. Nelle profondit\u00e0 della documentazione si pu\u00f2 trovare un riferimento a <code>delegate_to<\/code>, plugin di lookup locali, impostazioni specifiche per network-cli, jump host, ecc. Questi permettono di modificare leggermente il luogo di esecuzione delle attivit\u00e0. Ma dimenticateli. Ognuna di queste opzioni astute ha applicazioni molto specifiche e non sono affatto universali. Noi parliamo di cose fondamentali che tutti dovrebbero conoscere e utilizzare.<\/p>\n<p><\/p>\n<p>Se vuoi eseguire \"qualcosa\" \"da qualche parte\" \u2014 scrivi un play. Non un ruolo. Non un ruolo con moduli e delegati. Prendi e scrivi un play. In cui, nel campo hosts, elenchi dove eseguire, e in roles\/tasks \u2014 cosa eseguire.<\/p>\n<p><\/p>\n<p>Facile, giusto? E come potrebbe essere altrimenti?<\/p>\n<p><\/p>\n<p>Uno dei momenti caratteristici in cui le persone desiderano farlo non tramite un play, \u00e8 il \"ruolo che configura tutto\". Si desidera avere un ruolo che configuri e <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/it\/server\/dts-los-angeles\/\"   title=\"server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3633\">server<\/a> il primo tipo e server del secondo tipo.<\/p>\n<p><\/p>\n<p>Un esempio archetipico \u00e8 il monitoraggio. Si desidera avere un ruolo di monitoring che configuri il monitoraggio. Il ruolo di monitoring viene assegnato agli host di monitoraggio (nella relativa play). Ma, si scopre che per monitorare dobbiamo installare pacchetti sugli host che monitoriamo. Perch\u00e9 non usare un delegate? E deve anche configurare iptables. Delegate? E bisogna scrivere\/modificare la configurazione per il DBMS, affinch\u00e9 il monitoraggio possa avviarsi. Delegate! E se la creativit\u00e0 \u00e8 esplosa, si pu\u00f2 fare delega <code>include_role<\/code> in un ciclo interno con un filtro astuto sulla lista dei gruppi, e all'interno <code>include_role<\/code> si possono ancora fare <code>delegate_to<\/code> di nuovo. E cos\u00ec \u00e8 iniziato\u2026<\/p>\n<p><\/p>\n<p>Un buon desiderio \u2014 avere un unico ruolo di monitoring che \"fa tutto\" \u2014 ci conduce a un inferno da cui spesso c'\u00e8 una sola via d'uscita: riscrivere tutto da zero.<\/p>\n<p><\/p>\n<p>Dove \u00e8 avvenuto l'errore? Nel momento in cui hai scoperto che per eseguire il compito \"x\" sull'host X devi andare sull'host Y e fare \"y\", avresti dovuto semplicemente compiere un esercizio: andare e scrivere un play che su host Y esegue y. Non completare qualcosa in \"x\", ma scrivere da zero. Anche a costo di hardcodare delle variabili.<\/p>\n<p><\/p>\n<p>Sembra che nei paragrafi sopra sia tutto corretto. Ma questo non \u00e8 il tuo caso! Perch\u00e9 vuoi scrivere codice riutilizzabile, che sia DRY e somigli a una libreria, e devi cercare il metodo per farlo.<\/p>\n<p><\/p>\n<p>Qui si nasconde un altro errore grave. Un errore che ha trasformato molti progetti da scritti in modo accettabile (si pu\u00f2 fare meglio, ma funziona e \u00e8 facile da completare) in un terribile disastro, in cui persino l'autore non riesce a districarsi. Funziona, ma Dio non voglia che cambi qualcosa.<\/p>\n<p><\/p>\n<p>Questo errore suona cos\u00ec: un ruolo \u00e8 una funzione di libreria. Questa analogia ha distrutto cos\u00ec tante buone iniziative che \u00e8 solo triste da osservare. Un ruolo non \u00e8 una funzione di libreria. Non pu\u00f2 effettuare calcoli e non pu\u00f2 prendere decisioni a livello di play. Mi ricordate quali decisioni prende il play?<\/p>\n<p><\/p>\n<p>Grazie, hai ragione. Il play prende decisioni (piuttosto, contiene informazioni) su quali task e ruoli eseguire su quali host.<\/p>\n<p><\/p>\n<p>Se deleghi questa decisione al ruolo, e ci metti anche dei calcoli, ti condanni (e chiunque cerchi di decifrare il tuo codice) a un'esistenza misera. Il ruolo non decide dove deve essere eseguito. Questa decisione la prende il play. Il ruolo esegue ci\u00f2 che gli \u00e8 stato detto, nel luogo in cui gli \u00e8 stato detto.<\/p>\n<p><\/p>\n<p>Perch\u00e9 programmare in Ansible \u00e8 pericoloso e perch\u00e9 COBOL \u00e8 migliore di Ansible ne parleremo nel capitolo sulle variabili e jinja. Al momento diciamo solo una cosa: ogni tuo calcolo lascia un'impronta indelebile di modifica delle variabili globali, e non puoi farci nulla. Non appena due \"tracce\" si incrociano \u2014 tutto \u00e8 perso.<\/p>\n<p><\/p>\n<p>Nota per i pignoli: il ruolo pu\u00f2 certamente influenzare il controllo del flusso. Ci sono <code>delegate_to<\/code> e ha applicazioni ragionevoli. Ci sono <code>meta: end host\/play<\/code>. Ma! Ricorda, stiamo insegnando le basi? Dimenticati di <code>delegate_to<\/code>. Stiamo parlando del codice pi\u00f9 semplice e pi\u00f9 bello in Ansible. Che \u00e8 facile da leggere, scrivere, debuggare, testare e completare. Quindi, ancora una volta:<\/p>\n<p><\/p>\n<p><strong>solo il play decide su quali host ci\u00f2 viene eseguito.<\/strong><\/p>\n<p><\/p>\n<p>In questa sezione abbiamo esaminato il contrasto tra play e ruolo. Ora parleremo delle relazioni tra task e ruolo.<\/p>\n<p><\/p>\n<h1>Task e Ruoli<\/h1>\n<p><\/p>\n<p>Esaminiamo il play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: somegroup\n  pre_tasks:\n    - some_tasks1:\n  roles:\n     - role1\n     - role2\n  post_tasks:\n     - some_task2:\n     - some_task3:<\/code><\/pre>\n<p><\/p>\n<p>Supponiamo che tu debba fare foo. E appare cos\u00ec <code>foo: name=foobar state=present<\/code>. Dove dovresti scriverlo? in pre? post? Creare un ruolo?<\/p>\n<p><\/p>\n<p>\u2026 E dove sono finiti i task?<\/p>\n<p><\/p>\n<p>Torniamo di nuovo alle basi: il play. Se hai difficolt\u00e0 con questo argomento, non puoi usare il play come fondamento per tutto il resto, e il tuo risultato risulta \"instabile\".<\/p>\n<p><\/p>\n<p>Dispositivo play: direttiva hosts, impostazioni del play stesso e delle sezioni pre_tasks, tasks, roles, post_tasks. Gli altri parametri per il play non ci interessano al momento.<\/p>\n<p><\/p>\n<p>Ordine delle loro sezioni con i task e i ruoli: <code>pre_tasks<\/code>, <code>roles<\/code>, <code>tasks<\/code>, <code>post_tasks<\/code>. Poich\u00e9 l'ordine semantico tra <code>tasks<\/code> e <code>roles<\/code> non \u00e8 chiaro, le best practices dicono che dobbiamo aggiungere una sezione <code>tasks<\/code>, solo se non ci sono <code>roles<\/code>. Se ci sono <code>roles<\/code>, allora tutti i task allegati vengono posizionati nelle sezioni <code>pre_tasks<\/code>\/<code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>Rimane solo ci\u00f2 che \u00e8 semanticamente chiaro: prima <code>pre_tasks<\/code>, poi <code>roles<\/code>, poi <code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>Ma non abbiamo ancora risposto alla domanda: dove dobbiamo scrivere il richiamo del modulo <code>foo<\/code> ? Dobbiamo scrivere un ruolo intero per ogni modulo? O \u00e8 meglio avere un ruolo ampio per tutto? E se non \u00e8 un ruolo, dove scrivere \u2014 in pre o in post?<\/p>\n<p><\/p>\n<p>Se non c'\u00e8 una risposta argomentata a queste domande, \u00e8 un segno di mancanza di intuizione, cio\u00e8 quei \"fondamenti instabili\". Analizziamo la situazione. Prima domanda di controllo: Se il play ha... <code>pre_tasks<\/code> e <code>post_tasks<\/code> (e non ci sono n\u00e9 tasks n\u00e9 roles), potrebbe rompersi qualcosa se porto il primo task da <code>post_tasks<\/code> alla fine <code>pre_tasks<\/code>?<\/p>\n<p><\/p>\n<p>Naturalmente, la formulazione della domanda suggerisce che si romper\u00e0. Ma cosa in particolare?<\/p>\n<p><\/p>\n<p>\u2026 Handler. Leggere le basi rivela un fatto importante: tutti gli handler vengono eseguiti automaticamente dopo ogni sezione. Cio\u00e8, tutte le attivit\u00e0 vengono... <code>pre_tasks<\/code>, poi tutti i gestori che sono stati notificati. Poi vengono eseguiti tutti i ruoli e tutti i gestori che sono stati notificati nei ruoli. Poi <code>post_tasks<\/code> e i loro gestori.<\/p>\n<p><\/p>\n<p>Cos\u00ec, se trascini un task da <code>post_tasks<\/code> in <code>pre_tasks<\/code>, quindi, potenzialmente, la eseguirai prima dell'esecuzione dell'handler. Ad esempio, se in... <code>pre_tasks<\/code> si installa e configura <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/it\/server\/\"   title=\"server web\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1155\">server web<\/a>, e in <code>post_tasks<\/code> qualcosa viene inviato l\u00ec, allora spostare questo task nella sezione <code>pre_tasks<\/code> porter\u00e0 al fatto che al momento dell'\"invio\" il server non sar\u00e0 ancora avviato e tutto si rompir\u00e0.<\/p>\n<p><\/p>\n<p>E ora riflettiamo ancora una volta: perch\u00e9 abbiamo bisogno di <code>pre_tasks<\/code> e <code>post_tasks<\/code>? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0451 \u043d\u0443\u0436\u043d\u043e\u0435 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0445\u044d\u043d\u0434\u043b\u0435\u0440\u044b) \u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u043e\u043b\u0438. \u0410 <code>post_tasks<\/code> ci permetter\u00e0 di lavorare con i risultati dell'esecuzione dei ruoli (inclusi i gestori).<\/p>\n<p><\/p>\n<p>Un esperto di Ansible dir\u00e0 che c'\u00e8 <code>meta: flush_handlers<\/code>, ma perch\u00e9 abbiamo bisogno di flush_handlers, se possiamo contare sull'ordine di esecuzione delle sezioni nel play? Inoltre, l'uso di meta: flush_handlers pu\u00f2 causarci sorprese con gestori ripetuti, generare avvertimenti insoliti in caso di utilizzo di <code>when<\/code> a <code>block<\/code> e cos\u00ec via. Maggiore \u00e8 la tua conoscenza di Ansible, pi\u00f9 dettagli riuscirai a elencare per una soluzione \"astuta\". E una soluzione semplice \u2014 utilizzare una separazione naturale tra pre\/roles\/post \u2014 non genera problemi.<\/p>\n<p><\/p>\n<p>E, tornando al nostro 'foo'. Dove deve essere collocato? In pre, post o in roles? Ovviamente, dipende se abbiamo bisogno dei risultati del lavoro dell'handler per foo. Se non ne abbiamo bisogno, foo non deve essere inserito n\u00e9 in pre n\u00e9 in post \u2014 queste sezioni hanno un significato speciale \u2014 l'esecuzione delle attivit\u00e0 prima e dopo l'array principale di codice.<\/p>\n<p><\/p>\n<p>Ora la risposta alla domanda \"ruolo o attivit\u00e0\" si riduce a ci\u00f2 che \u00e8 gi\u00e0 presente nel play \u2014 se ci sono attivit\u00e0, allora bisogna aggiungere a tasks. Se ci sono ruoli \u2014 bisogna creare un ruolo (anche se composto da un'unica attivit\u00e0). Ricordo che tasks e roles non vengono utilizzati contemporaneamente.<\/p>\n<p><\/p>\n<p>Comprendere le basi di Ansible fornisce risposte fondate a quelli che sembrerebbero essere quesiti soggettivi.<\/p>\n<p><\/p>\n<h1>Task e ruoli (parte seconda)<\/h1>\n<p><\/p>\n<p>Ora discutiamo della situazione in cui stai appena iniziando a scrivere un playbook. Devi fare foo, bar e baz. Sono tre compiti, un ruolo o tre ruoli? Generalizzando la domanda: quando dovresti iniziare a scrivere ruoli? Qual \u00e8 il senso di scrivere ruoli quando puoi scrivere compiti?\u2026 E cos'\u00e8 un ruolo?<\/p>\n<p><\/p>\n<p>Uno degli errori pi\u00f9 gravi (ne ho gi\u00e0 parlato) \u00e8 considerare un ruolo come una funzione in una libreria di un programma. Come appare una descrizione generale di una funzione? Riceve argomenti in input, interagisce con cause esterne, produce effetti collaterali e restituisce un valore.<\/p>\n<p><\/p>\n<p>Ora, attenzione. Cosa di tutto ci\u00f2 pu\u00f2 essere fatto in un ruolo? Causare effetti collaterali \u2014 sempre possibile, questo \u00e8 l'essenza di Ansible \u2014 produrre effetti collaterali. Avere cause collaterali? Elementare. Ma per quanto riguarda \"passare un valore e restituirlo\" \u2014 qui le cose cambiano. In primo luogo, non puoi passare un valore a un ruolo. Puoi definire una variabile globale con una durata di vita pari al play nella sezione vars per il ruolo. Puoi definire una variabile globale con una durata di vita in play all'interno del ruolo. O addirittura con una durata pari al playbook (<code>set_fact<\/code>\/<code>register<\/code>). Ma non puoi avere \"variabili locali\". Non puoi \"ricevere un valore\" e \"restituirlo\".<\/p>\n<p><\/p>\n<p>Da ci\u00f2 ne deriva la cosa principale: non puoi scrivere nulla in ansible senza causare effetti collaterali. Modificare variabili globali \u00e8 sempre un effetto collaterale per una funzione. In Rust, per esempio, modificare una variabile globale \u00e8 <code>unsafe<\/code>. In Ansible, there is only one method to influence the values for a role. Note the words used: it is not 'pass a value to a role', but 'change the values that the role uses'. There is no isolation between roles. There is no isolation between tasks and roles.<\/p>\n<p><\/p>\n<p>In totale: <strong>un ruolo non \u00e8 una funzione<\/strong>.<\/p>\n<p><\/p>\n<p>Cosa c'\u00e8 di buono nei ruoli? Innanzitutto, i ruoli hanno valori predefiniti (<code>\/default\/main.yaml<\/code>), in secondo luogo i ruoli hanno directory aggiuntive per l'archiviazione dei file.<\/p>\n<p><\/p>\n<p>Cosa c'\u00e8 di buono nei valori predefiniti? Il fatto che, nella piuttosto distorta gerarchia delle variabili di Maslow, i valori predefiniti dei ruoli di Ansible sono i meno prioritari (esclusi i parametri della riga di comando di Ansible). Questo significa che se devi fornire valori predefiniti senza preoccuparti che questi sovrascrivano i valori provenienti dall'inventario o dalle variabili di gruppo, i valori predefiniti del ruolo sono l'unico posto giusto per te. (Sto un po' mentendo \u2014 ce ne sono anche altri <code>|d(your_default_here)<\/code>, ma se si parla di luoghi stabili \u2014 allora solo i valori predefiniti dei ruoli).<\/p>\n<p><\/p>\n<p>Cosa c'\u00e8 di buono nei ruoli? Il fatto che hanno le proprie directory. Queste sono directory per le variabili, sia costanti (cio\u00e8 calcolate per il ruolo), sia per quelle dinamiche (c'\u00e8 un qualche pattern o antipattern \u2014 <code>include_vars<\/code> insieme a <code>{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml<\/code>. Queste sono directory per <code>files\/<\/code>, <code>templates\/<\/code>. Inoltre, permettono ai ruoli di avere i loro moduli e plugin (<code>library\/<\/code>). However, compared to tasks in a playbook (where all this can also be), the benefit here is only that the files are not all mixed together, but divided into several separate piles.<\/p>\n<p><\/p>\n<p>Un altro aspetto: puoi cercare di creare ruoli che siano riutilizzabili (attraverso galaxy). Dopo l'introduzione delle collezioni, la diffusione dei ruoli pu\u00f2 essere considerata quasi dimenticata.<\/p>\n<p><\/p>\n<p>Pertanto, i ruoli hanno due caratteristiche importanti: hanno valori predefiniti (unica caratteristica) e permettono di strutturare il codice.<\/p>\n<p><\/p>\n<p>Returning to the initial question: when to use tasks and when to use roles? Tasks in the playbook are most often used either as 'glue' before\/after roles, or as a standalone building block (in which case there should be no roles in the code). A jumble of normal tasks mixed in with roles is undoubtedly disorderly. One should adhere to a specific style \u2014 either tasks or roles. Roles provide separation of entities and defaults, while tasks allow for faster code reading. Usually, in roles, more 'stationary' (important and complex) code is taken out, while in the style of tasks, auxiliary scripts are written.<\/p>\n<p><\/p>\n<p>Esiste la possibilit\u00e0 di fare import_role come task, ma se scrivi qualcosa del genere, preparati a dare una spiegazione del tuo gusto estetico sul motivo per cui vuoi farlo.<\/p>\n<p><\/p>\n<p>Un lettore pignolo potrebbe dire che i ruoli possono importare ruoli, che i ruoli possono avere dipendenze attraverso galaxy.yml, e c'\u00e8 anche un terribile e orribile <code>include_role<\/code> \u2014 ricordo che stiamo migliorando le nostre competenze in Ansible di base, non nella ginnastica artistica.<\/p>\n<p><\/p>\n<h1>Handler e task<\/h1>\n<p><\/p>\n<p>Discutiamo di un'altra cosa ovvia: gli handler. Saperli usare correttamente \u00e8 quasi un'arte. Qual \u00e8 la differenza tra un handler e un task?<\/p>\n<p><\/p>\n<p>Poich\u00e9 stiamo rinfrescando le basi, ecco un esempio:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group1\n  tasks:\n    - foo:\n      notify: handler1\n  handlers:\n     - name: handler1\n       bar:<\/code><\/pre>\n<p><\/p>\n<p>Handlers for a role are found in rolename\/handlers\/main.yaml. Handlers are shared among all participants in play: pre\/post_tasks can trigger the role's handlers, and a role can trigger handlers from the play. However, 'cross-role' calls to handlers cause much greater confusion than simply repeated trivial handlers. (Another best practice element is to avoid repeated handler names).<\/p>\n<p><\/p>\n<p>La principale differenza \u00e8 che un task viene eseguito (idempotentemente) sempre (pi\u00f9\/meno con tag e <code>when<\/code>), mentre un handler viene eseguito in base alla modifica dello stato (notify scatta solo se c'\u00e8 stato un cambiamento). Quali problematiche pu\u00f2 comportare? Ad esempio, il fatto che se riavvi il task senza cambiamenti, allora non verr\u00e0 eseguito l'handler. E perch\u00e9 potrebbe essere necessario eseguire un handler quando non c'\u00e8 stato cambiato nel task generatore? Ad esempio, perch\u00e9 qualcosa si \u00e8 rotto e c'\u00e8 stato un cambiamento, ma l'esecuzione non \u00e8 arrivata all'handler. Ad esempio, perch\u00e9 la rete \u00e8 andata temporaneamente gi\u00f9. La configurazione \u00e8 cambiata, il servizio non \u00e8 stato riavviato. Al prossimo avvio, la configurazione non cambia pi\u00f9, e il servizio rimane con la vecchia versione della configurazione.<\/p>\n<p><\/p>\n<p>The situation with configs is unsolvable (more precisely, one can invent a special restart protocol with file flags, etc., but that is no longer 'basic ansible' in any form). However, there is another common story: we installed the application and recorded it. <code>.service<\/code>-file, e ora vogliamo <code>daemon_reload<\/code> e <code>state=started<\/code>. E il posto naturale per questo sembra essere un handler. Ma se lo si trasforma da handler in un'attivit\u00e0 alla fine della lista delle attivit\u00e0 o in un ruolo, verr\u00e0 eseguito idempotentemente ogni volta. Anche se il playbook si interrompe a met\u00e0. Questo non risolve affatto il problema di restarted (non si pu\u00f2 creare un'attivit\u00e0 con l'attributo restarted, poich\u00e9 si perde l'idempotenza), ma \u00e8 sicuramente opportuno impostare state=started, la stabilit\u00e0 complessiva dei playbook aumenta, poich\u00e9 si riduce il numero di collegamenti e stati dinamici.<\/p>\n<p><\/p>\n<p>Another positive feature of a handler is that it does not clutter the output. No changes \u2014 no unnecessary skipped or ok in the output \u2014 it\u2019s easier to read. This is also a negative feature \u2014 if you find a typo in a linearly executed task on the first run, handlers will only be executed on changed, i.e., under certain conditions \u2014 very rarely. For example, the first time in your life after five years. And, of course, there will be a typo in the name and everything will break. And the second time, they cannot be triggered \u2014 there is no changed.<\/p>\n<p><\/p>\n<p>\u00c8 importante parlare della disponibilit\u00e0 delle variabili. Ad esempio, se si invia una notifica per un'attivit\u00e0 con un ciclo, cosa accadr\u00e0 alle variabili? Si pu\u00f2 indovinare analiticamente, ma non \u00e8 sempre banale, soprattutto se le variabili provengono da posti diversi.<\/p>\n<p><\/p>\n<p>Quindi i handler sono molto meno utili e molto pi\u00f9 problematici di quanto sembri. Se \u00e8 possibile scrivere qualcosa in modo elegante (senza fronzoli) senza handler, \u00e8 meglio farlo senza di essi. Se non riesco a farlo in modo elegante, \u00e8 meglio usare gli handler.<\/p>\n<p><\/p>\n<p>Un lettore attento fa notare giustamente che non abbiamo discusso <code>ascolta<\/code>, che un handler pu\u00f2 chiamare notify per un altro handler, che un handler pu\u00f2 includere import_tasks (che pu\u00f2 eseguire include_role con with_items), che il sistema degli handler in Ansible \u00e8 turing-completo, che gli handler da include_role si sovrappongono in modo curioso agli handler da play e cos\u00ec via - tutto ci\u00f2 \u00e8 chiaramente non \"fondamentale\").<\/p>\n<p><\/p>\n<p>Tuttavia, c'\u00e8 un certo WTF che \u00e8 in realt\u00e0 una funzionalit\u00e0, e di cui bisogna tenere conto. Se si esegue un'attivit\u00e0 con <code>delegate_to<\/code> e ha un notify, l'handler corrispondente viene eseguito senza <code>delegate_to<\/code>, cio\u00e8 sull'host a cui \u00e8 assegnato il play. (Anche se l'handler, ovviamente, pu\u00f2 avere <code>delegate_to<\/code> anch'esso).<\/p>\n<p><\/p>\n<p>Voglio anche dire qualche parola sui ruoli riutilizzabili. Prima dell'arrivo delle collezioni, c'era l'idea che fosse possibile creare ruoli universali che possono essere <code>ansible-galaxy install<\/code> E sono partito. Funziona su tutti i sistemi operativi in tutte le varianti in tutte le situazioni. Quindi, la mia opinione \u00e8: non funziona. Qualsiasi ruolo con supporto per 100500 casi \u00e8 destinato a profonde bug corner case. Possono essere tappati con un testing massiccio, ma come con qualsiasi testing, o hai il prodotto cartesiano dei valori di input e una funzione totale, oppure hai \"coperti scenari singoli\". La mia opinione \u00e8: \u00e8 molto meglio se il ruolo \u00e8 lineare (complessit\u00e0 ciclomatica 1). <code>include_vars<\/code>, supportando 100500 casi \u00e8 destinato a un abisso di bug corner case. Possono essere bloccati attraverso un test massiccio, ma come con qualsiasi test, o hai il prodotto cartesiano dei valori di input e una funzione totale, oppure hai \"coperto scenari specifici\". La mia opinione \u00e8 che sia molto meglio se il ruolo \u00e8 lineare (complessit\u00e0 ciclomatica 1).<\/p>\n<p><\/p>\n<p>Meno if ci sono (espliciti o dichiarativi - sotto forma di <code>when<\/code> in base a un insieme di variabili), migliore \u00e8 il ruolo. A volte \u00e8 necessario fare delle diramazioni, ma, ripeto, meno ce ne sono, meglio \u00e8. Quindi, sembra che un buon ruolo con galaxy (funziona, giusto!) con un sacco di <code>include_vars<\/code> possa essere meno preferibile rispetto a un \"proprio\" ruolo di cinque task. Il momento in cui un ruolo con galaxy \u00e8 migliore \u2014 \u00e8 quando inizi a scrivere qualcosa. Il momento in cui diventa peggiore \u2014 \u00e8 quando qualcosa si rompe, e hai il sospetto che sia a causa del \"ruolo con galaxy\". Lo apri e ci sono cinque inclusioni, otto elenchi di attivit\u00e0 e una pila <code>when<\/code> pu\u00f2 essere meno preferibile di un \"proprio\" ruolo di cinque task. Il momento in cui un ruolo da galaxy \u00e8 migliore \u00e8 quando inizi a scrivere qualcosa. Il momento in cui diventa peggiore \u00e8 quando qualcosa si rompe e sospetti che sia a causa del \"ruolo da galaxy\". Lo apri e ci sono cinque inclusioni, otto elenchi di task e una pila <code>when<\/code>\u2018... E devi districarti in questo. Invece di 5 task in un elenco lineare, in cui non c'\u00e8 niente da rompere.<\/p>\n<p><\/p>\n<h1>Un po' sull'inventario, variabili di gruppo, plugin host_group_vars, hostvars. Come collegare il nodo gordiano in uno spaghetto. Scope e precedenza delle variabili, modello di memoria Ansible. \"Ma dove dovremmo davvero conservare il nome utente per il database?\".<\/h1>\n<p><\/p>\n<ul>\n<li>Un po' su inventory, variabili di gruppo, plugin host_group_vars, hostvars. Come collegare spaghetti in un nodo gordiano. Scope e precedenza delle variabili, modello di memoria di Ansible. \"Allora dove si conserva effettivamente il nome utente per il database?\".<\/li>\n<li><code>\u2014 nosql notype nosense plastilina morbida. \u00c8 ovunque, anche dove non te lo aspetti. Un po' su<\/code> !!unsafe <code>e su un yaml gustoso.<\/code> Rilascio della distribuzione openSUSE Leap 15.2<\/li>\n<\/ul>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/508762\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c. \u0412 \u0445\u043e\u0434\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043e\u0448\u0438\u0431\u043e\u043a (\u043a\u0430\u043a \u0447\u0443\u0436\u0438\u0445, \u0442\u0430\u043a \u0438 \u0441\u0432\u043e\u0438\u0445), \u0430 \u0442\u0430\u043a \u0436\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439, \u044f \u043f\u043e\u043d\u044f\u043b \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0410\u043d\u0441\u0438\u0431\u043b\u0430 \u2014 \u043e\u043d\u0438 \u043b\u0435\u0437\u0443\u0442 \u0432 \u0441\u043b\u043e\u0436\u043d\u043e\u0435, \u043d\u0435 \u043e\u0441\u0432\u043e\u0438\u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e. \u0414\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0432\u0441\u0435\u043b\u0435\u043d\u0441\u043a\u043e\u0439 \u043d\u0435\u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0410\u043d\u0441\u0438\u0431\u043b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87084","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0441\u043d\u043e\u0432\u044b Ansible, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0448\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0438 \u2014 \u043a\u043e\u043c\u043e\u043a \u0441\u043b\u0438\u043f\u0448\u0438\u0445\u0441\u044f \u043c\u0430\u043a\u0430\u0440\u043e\u043d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-03T11:42:34+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-03T11:42:34+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Fondamenti di Ansible, senza i quali i tuoi playbook sono un grumo di pasta incollata | ProHoster","description":"\ud83e\udd47Fondamenti di Ansible, senza i quali i tuoi playbook sono un grumo di pasta incollata | ProHoster","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0441\u043d\u043e\u0432\u044b Ansible, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0448\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0438 \u2014 \u043a\u043e\u043c\u043e\u043a \u0441\u043b\u0438\u043f\u0448\u0438\u0445\u0441\u044f \u043c\u0430\u043a\u0430\u0440\u043e\u043d | ProHoster","og:description":"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-03T11:42:34+00:00","article:modified_time":"2020-07-03T11:42:34+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87084","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:58:53","updated":"2026-02-22 15:29:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/87084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=87084"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/87084\/revisions"}],"predecessor-version":[{"id":162161,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/87084\/revisions\/162161"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=87084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=87084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=87084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}