{"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":"Fondamenti di Ansible, senza i quali i tuoi playbook saranno un groviglio di pasta attaccata","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Faccio molte revisioni del codice di altri su Ansible e scrivo molto io stesso. Durante l'analisi degli errori (sia degli altri che dei miei) e in un certo numero di colloqui, ho capito l'errore principale che commettono gli utenti di Ansible: si avventurano in cose complesse senza aver prima padroneggiato le basi.<\/p>\n<p><\/p>\n<p>Per rimediare a questa ingiustizia universale, ho deciso di scrivere un'introduzione ad Ansible per coloro che gi\u00e0 lo conoscono. Avverto, non \u00e8 un riassunto delle guide, \u00e8 un long read con molte parole e poche immagini.<\/p>\n<p><\/p>\n<p>Il livello atteso del lettore \u00e8 di avere gi\u00e0 scritto diverse migliaia di righe di YAML, avendo gi\u00e0 qualcosa in produzione, ma '\u00e8 tutto un po' storto'.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>Titoli<\/h1>\n<p><\/p>\n<p>Il principale errore degli utenti 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. Ecco un esempio vivente: durante un colloquio, una persona che sosteneva di aver scritto molto in Ansible non \u00e8 stata in grado di rispondere alla domanda 'di quali elementi \u00e8 composto il playbook?'. E quando ho suggerito che 'ci si aspettava una risposta del tipo che il playbook \u00e8 composto da play', ha seguito un commento devastante 'noi non lo utilizziamo'. Le persone scrivono in Ansible per soldi e non utilizzano i play. <em>In realt\u00e0, lo usano, ma non sanno cosa sia.<\/em><\/p>\n<p><\/p>\n<p>Iniziamo quindi con le basi: come si chiamano le cose. Magari lo sai gi\u00e0, magari no, perch\u00e9 non ci hai fatto caso mentre leggevo la documentazione.<\/p>\n<p><\/p>\n<p>ansible-playbook esegue il playbook. Il 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 un playbook. Possiamo mostrare dove sono le role, dove sono i tasks. Ma dove si trova il play? E come si differenzia il play da role o playbook?<\/p>\n<p><\/p>\n<p>Tutto questo \u00e8 presente nella documentazione. Eppure, viene trascurato. I principianti perch\u00e9 ci sono troppe informazioni e non possono memorizzare tutto in una volta. Gli esperti perch\u00e9 sono 'cose ovvie'. Se sei esperto, rileggere queste pagine almeno una volta ogni sei mesi migliorer\u00e0 notevolmente il tuo codice.<\/p>\n<p><\/p>\n<p>Quindi, ricordate: un Playbook \u00e8 un elenco composto da play e <code>import_playbook<\/code>.<br \/>\nEcco 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 una play? A cosa serve?<\/p>\n<p><\/p>\n<p>La play \u00e8 un elemento chiave per il playbook, perch\u00e9 \u00e8 la play che collega l'elenco dei ruoli e\/o delle attivit\u00e0 con l'elenco degli host su cui 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 e cos\u00ec via. Questi permettono di cambiare leggermente il luogo di esecuzione delle attivit\u00e0. Ma dimenticate tutto ci\u00f2. Ognuna di queste opzioni astute ha applicazioni molto specifiche e non sono affatto universali. Noi stiamo parlando delle 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. Nel quale, nel campo hosts, elenchi dove eseguire, e in roles\/tasks, cosa eseguire.<\/p>\n<p><\/p>\n<p>Semplice, vero? E come potrebbe essere diversamente?<\/p>\n<p><\/p>\n<p>Uno dei momenti tipici in cui le persone sentono il desiderio di farlo non tramite 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> sia di primo tipo che server di secondo tipo.<\/p>\n<p><\/p>\n<p>Un esempio archetipico \u00e8 il monitoraggio. Vuoi avere un ruolo di monitoraggio che configuri il monitoraggio. Il ruolo di monitoraggio viene assegnato agli host di monitoraggio (nel corrispondente play). Ma si scopre che per il monitoraggio dobbiamo installare pacchetti sugli host che stiamo monitorando. Perch\u00e9 non utilizzare delegate? E dobbiamo anche configurare iptables. delegate? Dobbiamo anche scrivere\/modificare la configurazione per il DBMS, in modo che il monitoraggio possa passare. delegate! E se l'ispirazione scatta, si pu\u00f2 fare delega <code>include_role<\/code> in un ciclo annidato con un filtro astuto sulla lista dei gruppi, e dentro <code>include_role<\/code> si pu\u00f2 anche fare <code>delegate_to<\/code> ancora. E si parte...<\/p>\n<p><\/p>\n<p>Il desiderio positivo di avere un unico ruolo di monitoring che \"fa tutto\" ci conduce a un inferno dal quale l'unica via d'uscita \u00e8: 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 dovevi andare sull'host Y e fare \"y\", avresti dovuto compiere un semplice esercizio: andare e scrivere un play, che sull'host Y esegue y. Non aggiungere qualcosa in \"x\", ma scriverlo da zero. Anche con variabili hardcoded.<\/p>\n<p><\/p>\n<p>Sembra che nei paragrafi precedenti tutto sia stato detto correttamente. Ma questo non \u00e8 il tuo caso! Perch\u00e9 vuoi scrivere codice riutilizzabile, che sia DRY e simile a una libreria, e devi cercare un metodo per farlo.<\/p>\n<p><\/p>\n<p>Qui si cela un ulteriore grave errore. Un errore che ha trasformato molti progetti da scritti in modo tollerabile (si pu\u00f2 fare meglio, ma tutto funziona e si pu\u00f2 riprendere facilmente) in un vero incubo, in cui persino l'autore non riesce a districarsi. Funziona, ma Dio non voglia cambiare qualcosa.<\/p>\n<p><\/p>\n<p>Questo errore si presenta cos\u00ec: un ruolo \u00e8 una funzione di libreria. Questa analogia ha portato al fallimento di molte buone iniziative, ed \u00e8 davvero triste da osservare. Un ruolo non \u00e8 una funzione di libreria. Non pu\u00f2 eseguire calcoli e non pu\u00f2 prendere decisioni a livello di play. Ricordami, quali decisioni prende play?<\/p>\n<p><\/p>\n<p>Hai ragione. 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 a un ruolo, e ancora di pi\u00f9 con calcoli, condanni te stesso (e chiunque cerchi di capire il tuo codice) a una vita misera. Un ruolo non decide dove deve essere eseguito. Questa decisione spetta a play. Un ruolo fa ci\u00f2 che gli viene ordinato, dove gli viene ordinato.<\/p>\n<p><\/p>\n<p>Perch\u00e9 programmare in Ansible sia pericoloso e perch\u00e9 COBOL sia migliore di Ansible ne parleremo nel capitolo sulle variabili e jinja. Per ora, diciamo solo una cosa: ogni tua computazione lascia una traccia indelebile di modifica delle variabili globali, e non puoi fare nulla al riguardo. Non appena due \"tracce\" si incrociano, tutto \u00e8 perso.<\/p>\n<p><\/p>\n<p>Nota per i pignoli: un ruolo pu\u00f2 influenzare senza dubbio il controllo del flusso. <code>delegate_to<\/code> e ha applicazioni ragionevoli. Ci sono <code>meta: end host\/play<\/code>. Ma! Ricordate, stiamo insegnando le basi? Dimenticati di <code>delegate_to<\/code>. Stiamo parlando del codice pi\u00f9 semplice e bello su Ansible. Che \u00e8 facile da leggere, facile da scrivere, facile da debugare, facile da testare e facile da estendere. Quindi, di nuovo:<\/p>\n<p><\/p>\n<p><strong>play e solo play decidono su quali host eseguire cosa.<\/strong><\/p>\n<p><\/p>\n<p>In questa sezione abbiamo esaminato il confronto tra play e role. Ora parliamo dei rapporti tra tasks e role.<\/p>\n<p><\/p>\n<h1>Tasks e Ruoli<\/h1>\n<p><\/p>\n<p>Consideriamo 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 si scrive? In pre? Post? Creare un role?<\/p>\n<p><\/p>\n<p>\u2026 E dove sono finiti i tasks?<\/p>\n<p><\/p>\n<p>Ripartiamo dalle basi: il dispositivo play. Se non hai familiarit\u00e0 con questo argomento, non puoi usare play come fondamento per tutto il resto, e il tuo risultato risulta \"instabile\".<\/p>\n<p><\/p>\n<p>Struttura di play: direttiva hosts, impostazioni di play e sezioni pre_tasks, tasks, roles, post_tasks. Gli altri parametri per play non ci interessano al momento.<\/p>\n<p><\/p>\n<p>L'ordine delle loro sezioni con tasks e roles: <code>pre_tasks<\/code>, <code>roles<\/code>, <code>tasks<\/code>, <code>post_tasks<\/code>. Poich\u00e9 semanticamente l'ordine di esecuzione tra <code>tasks<\/code> e <code>roles<\/code> non \u00e8 chiaro, ma 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>, quindi tutti i task allegati vengono inseriti nella sezione <code>pre_tasks<\/code>\/<code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>Rimane solo ci\u00f2 che \u00e8 semantico: prima di tutto <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 la chiamata del modulo? <code>foo<\/code> Dobbiamo scrivere un ruolo per ogni modulo? O \u00e8 meglio avere un ruolo principale per tutto? E se non \u00e8 un ruolo, dove scrivere \u2014 nel pre o nel post?<\/p>\n<p><\/p>\n<p>Se non ci sono risposte argomentate a queste domande, \u00e8 un segno di mancanza di intuizione, proprio quelle \"fondamenta instabili\". Iniziamo a fare chiarezza. Prima di tutto, la domanda di controllo: se play ha <code>pre_tasks<\/code> e <code>post_tasks<\/code> (e non ci sono n\u00e9 tasks n\u00e9 roles), pu\u00f2 succedere che qualcosa si rompa se sposto 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 precisamente?<\/p>\n<p><\/p>\n<p>\u2026 Handler. Comprendere le basi rivela un fatto importante: tutti gli handler vengono flushati automaticamente dopo ogni sezione. Cio\u00e8, tutte le attivit\u00e0 vengono eseguite da <code>pre_tasks<\/code>, poi tutti i handler che sono stati notificati. Poi vengono eseguiti tutti i ruoli e tutti i handler che sono stati notificati nei ruoli. Poi <code>post_tasks<\/code> e i loro handler.<\/p>\n<p><\/p>\n<p>Quindi, se sposti un task da <code>post_tasks<\/code> in <code>pre_tasks<\/code>, quindi, potenzialmente, la eseguirai prima che l'handler venga eseguito. Ad esempio, se nel <code>pre_tasks<\/code> si installa e si 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 nella <code>post_tasks<\/code> c'\u00e8 qualcosa che viene inviato in esso, quindi il trasferimento di 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 romper\u00e0.<\/p>\n<p><\/p>\n<p>E ora ripensiamo, 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 (compresi 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 affidarci all'ordine di esecuzione delle sezioni nel play? Inoltre, l'uso di meta: flush_handlers pu\u00f2 portarci a risultati inaspettati con gestori ripetuti, facendoci ricevere avvisi strani nel caso di utilizzo <code>when<\/code> a <code>block<\/code> e cos\u00ec via. Pi\u00f9 conosci Ansible, pi\u00f9 sfumature potrai identificare per una soluzione \"astuta\". E una soluzione semplice \u2014 utilizzare una separazione naturale tra pre\/roles\/post \u2014 non comporta sfumature.<\/p>\n<p><\/p>\n<p>E torniamo al nostro 'foo'. Dove collocarlo? In pre, post o in roles? Ovviamente, dipende se abbiamo bisogno dei risultati del gestore per foo. Se non servono, allora foo non deve essere posizionato n\u00e9 in pre n\u00e9 in post: queste sezioni hanno un significato specifico \u2014 l'esecuzione dei task prima e dopo l'array di codice principale.<\/p>\n<p><\/p>\n<p>Ora la risposta alla domanda \"ruolo o task\" dipende da ci\u00f2 che \u00e8 gi\u00e0 presente nel play: se ci sono tasks, allora bisogna aggiungere nei tasks. Se ci sono roles, bisogna creare un ruolo (anche se composto da un solo task). Ricordo che tasks e roles non vengono usati insieme.<\/p>\n<p><\/p>\n<p>La comprensione delle basi di Ansible fornisce risposte ben fondate a quelle che sembrano domande soggettive.<\/p>\n<p><\/p>\n<h1>Tasks e ruoli (parte seconda)<\/h1>\n<p><\/p>\n<p>Discutiamo ora la situazione in cui stai iniziando a scrivere un playbook. Devi fare foo, bar e baz. Sono tre task, un ruolo o tre ruoli? In sintesi, quando dovresti iniziare a scrivere ruoli? Qual \u00e8 il significato di scrivere ruoli quando puoi scrivere task? \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 che un ruolo sia come una funzione in una libreria di un programma. Come appare la descrizione generalizzata di una funzione? Essa accetta argomenti in input, interagisce con cause collaterali, produce effetti collaterali e restituisce un valore.<\/p>\n<p><\/p>\n<p>Ora, attenzione. Cosa si pu\u00f2 fare in un ruolo? Chiamare side effects \u2014 sempre, \u00e8 proprio questo il senso di Ansible: generare side effects. Avere side causes? Elementare. Ma con \"passare un valore e restituirlo\" \u2014 qui non \u00e8 possibile. In primo luogo, non potete passare un valore a un ruolo. Potete impostare una variabile globale con una durata pari al play nella sezione vars per il ruolo. Potete impostare una variabile globale con una durata nel play all'interno del ruolo. O addirittura con una durata dell'intero playbook.<code>set_fact<\/code>\/<code>register<\/code>). Ma non puoi avere &quot;variabili locali&quot;. Non puoi &quot;assumere un valore&quot; e &quot;restituirlo&quot;.<\/p>\n<p><\/p>\n<p>Questo porta alla conclusione principale: non si pu\u00f2 scrivere nulla in ansible senza generare side effects. La modifica delle variabili globali \u00e8 sempre un side effect per una funzione. In Rust, per esempio, cambiare una variabile globale \u00e8 <code>unsafe<\/code>. E in Ansible \u2014 l'unico modo per influenzare i valori per il ruolo. Nota le parole utilizzate: non &quot;passare un valore al ruolo&quot;, ma &quot;modificare i valori che utilizza il ruolo&quot;. Non c'\u00e8 isolamento tra i ruoli. Non c'\u00e8 isolamento tra i task e i ruoli.<\/p>\n<p><\/p>\n<p>In totale: <strong>il ruolo non \u00e8 una funzione<\/strong>.<\/p>\n<p><\/p>\n<p>Quali sono i vantaggi di un ruolo? Innanzitutto, un ruolo ha dei valori predefiniti (<code>\/default\/main.yaml<\/code>), in secondo luogo, un ruolo dispone di cataloghi aggiuntivi per l'archiviazione dei file.<\/p>\n<p><\/p>\n<p>Quali sono dunque i vantaggi dei valori predefiniti? Nel contesto piuttosto distorto della piramide di Maslow riguardante le priorit\u00e0 delle variabili in Ansible, i valori predefiniti dei ruoli sono i meno prioritari (esclusi i parametri della riga di comando di Ansible). Ci\u00f2 significa che se devi fornire valori predefiniti senza preoccuparti che possano sovrascrivere i valori delle variabili di inventario o delle variabili di gruppo, i valori predefiniti del ruolo sono l'unico posto giusto per te. (Sto esagerando un po' \u2014 ce ne sono anche altri <code>|d(your_default_here)<\/code>, ma se parliamo di posizioni fisse, allora solo i valori predefiniti dei ruoli).<\/p>\n<p><\/p>\n<p>Cosa rende ancora migliori i ruoli? Il fatto che abbiano i propri cataloghi. Si tratta di cataloghi per le variabili, sia statiche (ossia calcolate per il ruolo) che dinamiche (c'\u00e8 un certo pattern o anti-pattern chiamato \u2014 <code>include_vars<\/code> insieme a <code>{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml<\/code>.). Questi sono cataloghi per <code>files\/<\/code>, <code>templates\/<\/code>. Inoltre, consente ai ruoli di avere i propri moduli e plugin (<code>library\/<\/code>). Ma, rispetto ai task nel playbook (che pu\u00f2 avere anche tutto questo), il vantaggio qui \u00e8 solo che i file non sono accumulati in un unico posto, ma in diverse pile separate.<\/p>\n<p><\/p>\n<p>Un altro aspetto: si possono cercare di realizzare ruoli che saranno disponibili per il riutilizzo (tramite galaxy). Dopo l'introduzione delle raccolte, la distribuzione dei ruoli pu\u00f2 considerarsi quasi dimenticata.<\/p>\n<p><\/p>\n<p>Cos\u00ec, i ruoli presentano due caratteristiche importanti: hanno dei valori predefiniti (una caratteristica unica) e permettono di strutturare il codice.<\/p>\n<p><\/p>\n<p>Tornando alla domanda originale: quando utilizzare i task e quando i ruoli? I task nel playbook sono spesso usati o come \"colla\" prima\/dopo i ruoli, oppure come elementi costitutivi autonomi (in tal caso nel codice non dovrebbero esserci ruoli). Una mescolanza di task normali con i ruoli \u00e8 decisamente disordinata. \u00c8 necessario mantenere uno stile specifico: o task, o ruoli. I ruoli offrono una separazione delle entit\u00e0 e valori predefiniti, i task permettono di leggere il codice pi\u00f9 rapidamente. Di solito, nei ruoli si colloca codice pi\u00f9 \"stazionario\" (importante e complesso), mentre nello stile dei task si scrivono script ausiliari.<\/p>\n<p><\/p>\n<p>\u00c8 possibile fare l'importazione di un ruolo come attivit\u00e0, ma se lo fai, preparati a giustificare il tuo bisogno di farlo.<\/p>\n<p><\/p>\n<p>Un lettore pignolo potrebbe dire che i ruoli possono importare ruoli, che i ruoli possono avere una dipendenza tramite galaxy.yml, e c'\u00e8 anche il terribile e spaventoso <code>include_role<\/code> \u2014 ricordo che stiamo migliorando le competenze di base in Ansible, non nella ginnastica ritmica.<\/p>\n<p><\/p>\n<h1>Gestori e attivit\u00e0<\/h1>\n<p><\/p>\n<p>Discutiamo un'altra cosa ovvia: i gestori. Saperli usare correttamente \u00e8 quasi un'arte. Qual \u00e8 la differenza tra un gestore e un'attivit\u00e0?<\/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>Nei ruoli, i handler si trovano in rolename\/handlers\/main.yaml. Gli handler vengono condivisi tra tutti i partecipanti al play: pre\/post_tasks possono richiamare gli handler del ruolo, mentre il ruolo pu\u00f2 richiamare gli handler dal play. Tuttavia, le chiamate agli handler \"cross-ruolo\" suscitano molto pi\u00f9 wtf rispetto alla ripetizione triviale di un handler. (Un altro elemento delle best practices \u00e8 cercare di evitare ripetizioni nei nomi degli handler).<\/p>\n<p><\/p>\n<p>La principale differenza \u00e8 che un'attivit\u00e0 viene eseguita (idempotentemente) sempre (pi\u00f9\/meno tag e <code>when<\/code>), e un handler \u2014 per la modifica dello stato (notify si attiva solo se \u00e8 stato cambiato). Qual \u00e8 il rischio? Ad esempio, se al successivo avvio non c'\u00e8 stato nessun cambiamento, allora non ci sar\u00e0 nemmeno l'handler. Perch\u00e9 potremmo avere bisogno di eseguire l'handler quando non ci sono stati cambiamenti nel task generante? Ad esempio, perch\u00e9 qualcosa \u00e8 andato storto e c'\u00e8 stato un cambiamento, ma l'esecuzione non \u00e8 arrivata all'handler. Ad esempio, perch\u00e9 la rete era momentaneamente gi\u00f9. La configurazione \u00e8 cambiata, ma il servizio non \u00e8 stato riavviato. Al successivo avvio, la configurazione non cambier\u00e0 pi\u00f9 e il servizio rimarr\u00e0 con la vecchia versione della configurazione.<\/p>\n<p><\/p>\n<p>La situazione con la configurazione non \u00e8 risolvibile (o meglio, si potrebbe inventare un protocollo speciale di riavvio con flag di file e simili, ma questo non \u00e8 pi\u00f9 'basic ansible' in nessun modo). Tuttavia, c'\u00e8 un'altra storia comune: abbiamo installato un'applicazione, l'abbiamo registrata. <code>.service<\/code>-file, e ora vogliamo <code>daemon_reload<\/code> e <code>state=started<\/code>. E il posto naturale per questo sembra essere il handler. Ma se lo rendi non un handler ma un task alla fine della lista dei task o una funzione, allora verr\u00e0 eseguito idempotentemente ogni volta. Anche se il playbook si \u00e8 interrotto a met\u00e0. Questo non risolve affatto il problema di restarted (non puoi impostare un task con l'attributo restarted, poich\u00e9 si perde l'idempotenza), ma \u00e8 sicuramente utile impostare state=started, in quanto la stabilit\u00e0 complessiva del playbook aumenta, poich\u00e9 si riducono le interconnessioni e lo stato dinamico.<\/p>\n<p><\/p>\n<p>Un'altra caratteristica positiva del handler \u00e8 che non intasa l'output. Se non ci sono state modifiche, non ci sono output aggiuntivi come skipped o ok, il che rende la lettura pi\u00f9 facile. Tuttavia, questo \u00e8 anche un difetto: se trovi un errore di battitura in un task eseguito linearmente al primo tentativo, gli handlers verranno eseguiti solo se ci sono stati cambiamenti, ovvero in determinate condizioni \u2014 molto raramente. Ad esempio, la prima volta nella vita dopo cinque anni. E, naturalmente, ci sar\u00e0 un errore nel nome e tutto si romper\u00e0. La seconda volta non si pu\u00f2 riavviare \u2014 non ci sono cambiamenti.<\/p>\n<p><\/p>\n<p>\u00c8 importante considerare la disponibilit\u00e0 delle variabili. Ad esempio, se si utilizza notify per un'attivit\u00e0 con ciclo, quali variabili saranno disponibili? Si pu\u00f2 dedurre analiticamente, ma non \u00e8 sempre banale, specialmente se le variabili provengono da fonti diverse.<\/p>\n<p><\/p>\n<p>\u2026 Quindi, gli handlers sono molto meno utili e molto pi\u00f9 problematici di quanto sembri. Se \u00e8 possibile scrivere qualcosa di bello (senza trucchi) senza handlers, \u00e8 meglio farlo senza di essi. Se non riesci a farlo bene, \u00e8 meglio usarli.<\/p>\n<p><\/p>\n<p>Un lettore attento fa giustamente notare che non abbiamo discusso <code>listen<\/code>, che un handler pu\u00f2 chiamare notify per un altro handler, che un handler pu\u00f2 includere import_tasks (che pu\u00f2 utilizzare include_role con with_items), che il sistema di handler in Ansible \u00e8 turing-completo, che gli handler provenienti da include_role si intrecciano curiosamente con gli handler del play, ecc. \u2014 tutto questo chiaramente non \u00e8 \"fondamentale\".<\/p>\n<p><\/p>\n<p>Tuttavia, c'\u00e8 un certo WTF che in realt\u00e0 \u00e8 una funzionalit\u00e0 e di cui bisogna tenere conto. Se avete un'attivit\u00e0 che viene eseguita con <code>delegate_to<\/code> e ha un notify, l'handler corrispondente viene eseguito senza <code>delegate_to<\/code>, cio\u00e8 sull'host assegnato al play. (Anche se l'handler, ovviamente, potrebbe avere <code>delegate_to<\/code> anch'esso).<\/p>\n<p><\/p>\n<p>Voglio dire due parole sui ruoli riutilizzabili. Prima dell'arrivo delle collezioni, si pensava che fosse possibile creare ruoli universali, che si potessero <code>ansible-galaxy install<\/code> e via. Funziona su tutti i sistemi operativi in tutte le situazioni. Tuttavia, la mia opinione \u00e8 che non funziona. Qualsiasi ruolo con supporto per 100500 casi \u00e8 destinato a essere sommerso da bug corner case. Possono essere mitigati con test approfonditi, ma come per qualsiasi testing, o avete il prodotto cartesiano dei valori in ingresso con una funzione totale, oppure avete \"coperti singoli scenari\". La mia opinione \u00e8 che \u00e8 molto meglio avere un ruolo lineare (complessit\u00e0 ciclomatica 1). <code>include_vars<\/code>, il supporto per 100500 casi \u00e8 destinato ad abissi di bug corner case. Possono essere affrontati con massicci test, ma come per qualsiasi test, o avete un prodotto cartesiano degli input e una funzione totale, oppure \"scenari specifici coperti\". Secondo me, \u00e8 molto meglio se il ruolo \u00e8 lineare (complessit\u00e0 ciclomatica 1).<\/p>\n<p><\/p>\n<p>Meno if ci sono (espliciti o dichiarativi \u2014 nella forma <code>when<\/code> in base a un insieme di variabili), migliore \u00e8 il ruolo. A volte \u00e8 necessario fare ramificazioni, ma, ripeto, meno ce ne sono, meglio \u00e8. Quindi, sembra un buon ruolo con galaxy (funziona, giusto!) con una serie di <code>include_vars<\/code> per il set di variabili), tanto migliore \u00e8 il ruolo. A volte \u00e8 necessario fare delle diramazioni, ma, ripeto, meno ce ne sono, meglio \u00e8. Quindi sembra essere un buon ruolo con galaxy (funziona, dopotutto!) con un sacco di <code>when<\/code> pu\u00f2 essere meno preferibile rispetto a un \"proprio\" ruolo di cinque attivit\u00e0. Il momento in cui un ruolo con galaxy \u00e8 migliore \u2014 \u00e8 quando si inizia a scrivere qualcosa. Il momento in cui diventa peggiore \u2014 \u00e8 quando qualcosa si rompe, e sospettate che sia a causa di \"un ruolo con galaxy\". Lo aprite e trovate cinque inclusioni, otto elenchi di attivit\u00e0 e una pila <code>when<\/code>\u2018\u2026 E bisogna capirci dentro. Invece di 5 attivit\u00e0 in un elenco lineare, dove non c'\u00e8 nemmeno nulla da rompere.<\/p>\n<p><\/p>\n<h1>Nelle parti successive<\/h1>\n<p><\/p>\n<ul>\n<li>Un po' di inventario, variabili di gruppo, plugin host_group_vars, hostvars. Come legare un nodo gordiano dagli spaghetti. Ambito e precedenza delle variabili, modello di memoria di Ansible. \"Ma dove dobbiamo tenere il nome utente per il database?\".<\/li>\n<li><code>jinja: {{ jinja }}<\/code> \u2014 nosql notype nosense plastilina morbida. \u00c8 ovunque, anche nei posti in cui non te lo aspetti. Un po' su <code>!!unsafe<\/code> e delizioso yaml.<\/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 4.9.10 - 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. \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\" \/>\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) 4.9.10\" \/>\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. \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\" \/>\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\udd47 Fondamenti di Ansible, senza i quali i vostri playbook sono un groviglio di pasta attaccata | ProHoster","description":"Faccio molte recensioni del codice di altre persone su Ansible e scrivo molto io stesso. Durante l'analisi degli errori (sia degli altri che dei miei), nonch\u00e9 in alcune interviste, ho compreso il principale errore che commettono gli utilizzatori di Ansible: si avventurano in complessit\u00e0 senza aver prima padroneggiato le basi. Per correggere questa ingiustizia universale, ho deciso di scrivere un'introduzione ad Ansible.","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. \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","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"},"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}]}}