{"id":80305,"date":"2020-05-05T01:42:50","date_gmt":"2020-05-04T23:42:50","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek"},"modified":"2020-05-05T01:42:50","modified_gmt":"2020-05-04T23:42:50","slug":"kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek","title":{"rendered":"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/b8981189e3a2d7f8429757cd521b7583.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Questa \u00e8 la trascrizione <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=GdrJv5oypfg\">dell'esibizione<\/a><\/noindex> con <noindex><a rel=\"nofollow\" href=\"https:\/\/www.meetup.com\/DevOps-40\/events\/269140089\/\">DevOps-40 2020-03-18<\/a><\/noindex>:<\/p>\n<p><\/p>\n<p>A partire dal secondo commit, qualsiasi codice diventa legacy, poich\u00e9 le idee iniziali iniziano a divergere dalla dura realt\u00e0. Non \u00e8 n\u00e9 buono n\u00e9 cattivo, \u00e8 una condizione con cui \u00e8 difficile discutere e con la quale \u00e8 necessario convivere. Parte di questo processo \u00e8 il refactoring. Refactoring dell'Infrastructure as Code. Inizia la storia su come rifattorizzare Ansible in un anno senza perdere la testa.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"zarozhdenie-legacy\">Nascita del Legacy<\/h2>\n<p><\/p>\n<h3 id=\"den--1-nulevoy-pacient\">Giorno n. 1: Il paziente zero<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/086414710864293a91a37785854bc096.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'era una volta un progetto condizionale. Aveva un team di sviluppo Dev e ingegneri Ops. Entrambi cercavano di risolvere la stessa questione: come distribuire server e avviare l'applicazione. Il problema era che ciascun team affrontava questa questione a modo suo. Sul progetto si decise di utilizzare Ansible per sincronizzare le conoscenze tra i team Dev e Ops.<\/p>\n<p><\/p>\n<h3 id=\"den--89-zarozhdenie-legacy\">Giorno n. 89: Nascita del Legacy<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/329bc3f190ca4d6519be6ac94026bc6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Senzi rendersene conto, volevano fare del loro meglio, ma \u00e8 diventato legacy. Come \u00e8 possibile?<\/p>\n<p><\/p>\n<ul>\n<li>Abbiamo un compito urgente, faremo un hack veloce \u2014 poi lo sistemeremo.<\/li>\n<li>Non \u00e8 necessario scrivere documentazione, \u00e8 tutto chiaro su cosa sta succedendo qui.<\/li>\n<li>So Ansible \/ Python \/ Bash \/ Terraform! Guardate come posso destreggiarmi!<\/li>\n<li>Sono un Full Stack Overflow Developer e ho copiato questo da stackoverflow; non so come funzioni, ma sembra interessante e risolve il problema.<\/li>\n<\/ul>\n<p><\/p>\n<p>Alla fine si pu\u00f2 ottenere un codice di aspetto strano, per il quale non esiste documentazione, non \u00e8 chiaro cosa faccia, se sia necessario, ma il problema \u00e8 che \u00e8 necessario svilupparlo, apportare modifiche e aggiungere soluzioni palliative, peggiorando ulteriormente la situazione.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: localhost\n  tasks:\n    - shell: echo -n Z &gt;&gt; a.txt &amp;&amp; cat a.txt\n      register: output\n      delay: 1\n      retries: 5\n      until: not output.stdout.find(\"ZZZ\")<\/code><\/pre>\n<p><\/p>\n<h3 id=\"den--109-osoznanie-problemy\">Giorno n. 109: Comprensione del problema<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/b7da9f6aecc5bebab6072ba6e5dfa824.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Il modello IaC originariamente concepito e implementato smette di rispondere alle richieste degli utenti \/ del business \/ di altri team, il tempo per apportare modifiche all'infrastruttura smette di essere accettabile. In questo momento si comprende che \u00e8 giunto il momento di agire.<\/p>\n<p><\/p>\n<h2 id=\"refaktoring-iac\">Refactoring IaC<\/h2>\n<p><\/p>\n<h3 id=\"den--139-a-vam-tochno-nuzhen-refaktoring\">Giorno n. 139: Hai davvero bisogno di un refactoring?<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/881455f096870d51bc2b9b8f87f171b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prima di lanciarti nel refactoring devi rispondere a una serie di domande importanti:<\/p>\n<p><\/p>\n<ol>\n<li>Perch\u00e9 hai bisogno di tutto questo?<\/li>\n<li>Hai tempo?<\/li>\n<li>Hai conoscenze sufficienti?<\/li>\n<\/ol>\n<p><\/p>\n<p>Se non sai come rispondere a queste domande, il refactoring potrebbe non mai iniziare o potrebbe semplicemente peggiorare. Poich\u00e9 hai gi\u00e0 avuto esperienze simili. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/467171\/\">Cosa ho appreso testando 200.000 righe di codice infrastrutturale.<\/a><\/noindex>), \u00e8 arrivata una richiesta dal progetto per aiutare a correggere i ruoli e coprirli con test.<\/p>\n<p><\/p>\n<h3 id=\"den--149-podgotovka-refaktoringa\">Giorno n. 149: Preparazione del refactoring<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/3e2d66a81cd162dcb4181f3914fc132d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La priorit\u00e0 \u00e8 prepararsi. Definire cosa faremo. Per questo, comunichiamo, identifichiamo i punti critici e valutiamo le possibili soluzioni. Fissiamo in qualche modo i concetti ricevuti, ad esempio un articolo in confluence, in modo da non perderci di vista alle domande come \"come \u00e8 meglio?\" o \"come \u00e8 giusto?\". Nel nostro caso, abbiamo seguito l'idea <em>dividi e conquista<\/em>: scomponiamo l'infrastruttura in piccoli pezzi \/ mattoncini. Questo approccio consente di prendere un pezzo isolato dell'infrastruttura, capire cosa fa, coprirlo con test e modificarlo senza temere di rompere qualcosa.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/a0ea12ae6568d5c7e97469eaf404d608.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Di conseguenza, il testing dell'infrastruttura diventa la pietra angolare e qui vale la pena menzionare la piramide del testing dell'infrastruttura. Proprio come nell'ambito dello sviluppo, ma per l'infrastruttura: partiamo da test rapidi e poco costosi che verificano semplici aspetti, come i margini, fino a test completi e costosi che distribuiscono un'infrastruttura intera.<\/p>\n<p><\/p>\n<h4 id=\"popytki-testirovaniya-ansible\">Tentativi di testing Ansible<\/h4>\n<p><\/p>\n<p>Prima di descrivere come abbiamo testato Ansible nel progetto, descriver\u00f2 i tentativi e gli approcci che ho dovuto utilizzare in precedenza per capire il contesto delle decisioni prese.<\/p>\n<p><\/p>\n<h5 id=\"den---997-sds-provision\">Giorno n\u00b0 -997: Provisionamento SDS<\/h5>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/3d93865fb03c7d7baa055b99e21d9ae9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La prima volta che ho testato Ansible \u00e8 stata in un progetto di sviluppo SDS (Software Defined Storage). Esiste un articolo separato su questo argomento.<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/342216\/\">Come rompere biciclette sopra stampelle durante il test della propria distribuzione<\/a><\/noindex>, ma per dirla brevemente, abbiamo ottenuto una piramide rovesciata di test e spendevamo dai 60 ai 90 minuti su un singolo ruolo, il che \u00e8 lungo. La base era composta da test e2e, ovvero implementavamo un'installazione completa e poi la testavamo. Inoltre, pesava il fatto che stessimo inventando la nostra bicicletta. Ma devo ammettere che questa soluzione funzionava e permetteva di rilasciare in modo stabile.<\/p>\n<p><\/p>\n<h5 id=\"den---701-ansible-i-test-kitchen\">Giorno n\u00b0 -701: Ansible e test kitchen<\/h5>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/1b87eca5b01cace01b48edaf28a4ab7d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lo sviluppo dell'idea di testare Ansible ha portato all'uso di strumenti pronti, in particolare test kitchen \/ kitchen-ci e inspec. La scelta \u00e8 stata influenzata dalla conoscenza di Ruby (pi\u00f9 dettagli nell'articolo su Habr: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/437004\/\">I programmatori YML sognano di testare Ansible?<\/a><\/noindex>) funzionava pi\u00f9 velocemente, circa 40 minuti per 10 ruoli. Creavamo un insieme di macchine virtuali e all'interno eseguivamo i test.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/345fe1c82dde1e6a94978781c90f8a85.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In generale, la soluzione funzionava, ma c'era un certo malessere a causa dell'eterogeneit\u00e0. Quando abbiamo aumentato il numero di test di 13 ruoli di base e 2 meta-ruoli combinando ruoli pi\u00f9 piccoli, i test sono impazziti, durando 70 minuti, quasi il doppio. Era difficile parlare di pratiche di XP (extreme programming) poich\u00e9 nessuno vorrebbe aspettare 70 minuti. Questo ha portato a un cambiamento di approccio.<\/p>\n<p><\/p>\n<h5 id=\"den---601-ansible-i-molecule\">Giorno n\u00b0 -601: Ansible e molecule<\/h5>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/37e144725fff4adda585781d057782ec.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Concettualmente \u00e8 simile a testkitchen, solo che abbiamo trasferito il test dei ruoli in docker e cambiato stack. Di conseguenza, il tempo si \u00e8 ridotto a stabili 20-25 minuti per 7 ruoli.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/640075d7087c1bc2337cb82ad412c6b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aumentando il numero dei ruoli testati a 17 e il linting di 45 ruoli, siamo riusciti a eseguire tutto in 28 minuti su 2 jenkins slave.<\/p>\n<p><\/p>\n<h3 id=\"den--167-dobavlyaem-na-proekt-testy-ansible\">Giorno n\u00b0 167: Aggiungiamo test Ansible al progetto<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/e62261eb4000f2bc4df4cea398d38276.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Affrontare subito la refactoring del task, probabilmente non sar\u00e0 possibile. Il task deve essere misurabile, in modo da poterlo suddividere in pezzi pi\u00f9 piccoli e mangiare l'elefante a piccoli bocconi. \u00c8 importante capire se si sta muovendosi nella giusta direzione e quanto lungo sar\u00e0 il percorso.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/daf1f9ba63e7122d5d39311b35de19a2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In generale, non \u00e8 cos\u00ec importante come venga fatto, si possono scrivere appunti, attaccare post-it all'armadio, creare task in jira oppure utilizzare Google Docs per annotare lo stato attuale. Il punto \u00e8 che il processo non \u00e8 immediato, sar\u00e0 lungo e noioso. \u00c8 improbabile che qualcuno desideri che, durante il refactoring, tu possa esaurire le idee, stancarti e rinunciare.<\/p>\n<p><\/p>\n<p>Il refactoring \u00e8 semplice:<\/p>\n<p><\/p>\n<ul>\n<li>Mangia.<\/li>\n<li>Riposa.<\/li>\n<li>Codifica.<\/li>\n<li>Test IaC.<\/li>\n<li>Ripeti.<\/li>\n<\/ul>\n<p><\/p>\n<p>E cos\u00ec continuiamo finch\u00e9 non raggiungiamo l'obiettivo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/222fe586d3e4e0bc23051fff1eb7bff4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Potrebbe non essere possibile iniziare a testare tutto subito, quindi il nostro primo compito \u00e8 stato cominciare con il linting e il controllo della sintassi. <\/p>\n<p><\/p>\n<h3 id=\"den--181-green-build-master\">Giorno n. 181: Green Build Master<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/86cf52ede5fd61411e2b87a132c7f386.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Il linting \u00e8 un piccolo primo passo verso il Green Build Master. Non romper\u00e0 quasi nulla, ma aiuter\u00e0 a perfezionare i processi e a ottenere build verdi in Jenkins. L'idea \u00e8 di sviluppare abitudini nel team:<\/p>\n<p><\/p>\n<ul>\n<li>I test rossi sono un problema.<\/li>\n<li>Se arrivi a correggere qualcosa, migliora anche il codice, rendendolo un po' migliore rispetto a com'era prima.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"den--193-ot-lintovki-k-unit-testam\">Giorno n. 193: Dal linting ai test unitari.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/2f79eb411cf64976459c7fc53f22b2fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Stabilendo il processo di deployment del codice, si pu\u00f2 avviare il processo di miglioramento graduale: sostituendo il linting con l'esecuzione dei ruoli, anche senza idempotenza. \u00c8 fondamentale comprendere come applicare i ruoli e come funzionano.<\/p>\n<p><\/p>\n<h3 id=\"den--211-ot-unit-k-integration-testam\">Giorno n. 211: Dai test unitari ai test di integrazione<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/9cfeb70b7b637eed4d0c93eb87d9d254.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quando la maggior parte dei ruoli \u00e8 coperta da test unitari e tutto \u00e8 correttamente lintato, si pu\u00f2 passare all'aggiunta dei test di integrazione. Ossia, testare non un singolo mattone dell'infrastruttura, ma le loro combinazioni, per esempio una configurazione completa di un'istanza.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/c9cdcde1260df9837b2053b2cc811c84.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Su Jenkins abbiamo generato molte fasi che lintano i ruoli\/ playbook in parallelo, poi i test unitari nei container e alla fine i test di integrazione.<\/p>\n<p><\/p>\n<h4 id=\"jenkins--docker--ansible--tests\">Jenkins + Docker + Ansible = Test<\/h4>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/218b1d768d2b284d18cfcba2370e080a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ol>\n<li>Controlla il repo e genera le fasi di build.<\/li>\n<li>Esegui le fasi di linting dei playbook in parallelo.<\/li>\n<li>Esegui le fasi di linting dei ruoli in parallelo.<\/li>\n<li>Esegui le fasi di controllo della sintassi dei ruoli in parallelo.<\/li>\n<li>Esegui le fasi di test dei ruoli in parallelo.\n<ol>\n<li>Lint del ruolo.<\/li>\n<li>Controlla le dipendenze dagli altri ruoli.<\/li>\n<li>Controlla la sintassi.<\/li>\n<li>Crea un'istanza Docker<\/li>\n<li>Esegui molecule\/default\/playbook.yml.<\/li>\n<li>Controlla l'idempotenza.<\/li>\n<\/ol>\n<\/li>\n<li>Esegui i test di integrazione<\/li>\n<li>Fine<\/li>\n<\/ol>\n<p><\/p>\n<h3 id=\"den--271-bus-factor\">Giorno n. 271: Bus Factor<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/eb1da11eb32f3f64d573e0414f0e05ba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Inizialmente, un piccolo gruppo di persone si occupava del refactoring. Effettuavano revisioni del codice nel master. Con il tempo, il team ha sviluppato competenze su come scrivere codice e le revisioni hanno contribuito alla diffusione delle conoscenze sull'infrastruttura e su come \u00e8 strutturata. La peculiarit\u00e0 era che i revisori venivano selezionati a turno, secondo un calendario, cio\u00e8 con una certa dose di probabilit\u00e0 si finiva per lavorare su una nuova area dell'infrastruttura.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/5ca2cf914f32f69f8a84d6c5bd4e5114.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E qui deve essere comodo. Comodo fare revisioni, vedere in quale compito sono state effettuate, la cronologia delle discussioni. Abbiamo integrato jenkins + bitbucket + jira.<\/p>\n<p><\/p>\n<p>Ma la revisione di per s\u00e9 non \u00e8 una panacea. Ad un certo punto, \u00e8 passato nel master un codice che ci ha causato test intermittenti:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- get_url:\n    url: \"{{ actk_certs }}\/{{ item.1 }}\"\n    dest: \"{{ actk_src_tmp }}\/\"\n    username: \"{{ actk_mvn_user }}\"\n    password: \"{{ actk_mvn_pass }}\"\n  with_subelements:\n    - \"{{ actk_cert_list }}\"\n    - \"{{ actk_certs }}\"\n  delegate_to: localhost\n\n- copy:\n    src: \"{{ actk_src_tmp }}\/{{ item.1 }}\"\n    dest: \"{{ actk_dst_tmp }}\"\n  with_subelements:\n    - \"{{ actk_cert_list }}\"\n    - \"{{ actk_certs }}\"<\/code><\/pre>\n<p><\/p>\n<p>Poi \u00e8 stato corretto, ma \u00e8 rimasto un retrogusto amaro.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">get_url:\n    url: \"{{ actk_certs }}\/{{ actk_item }}\"\n    dest: \"{{ actk_src_tmp }}\/{{ actk_item }}\"\n    username: \"{{ actk_mvn_user }}\"\n    password: \"{{ actk_mvn_pass }}\"\n  loop_control:\n    loop_var: actk_item\n  with_items: \"{{ actk_cert_list }}\"\n  delegate_to: localhost\n\n- copy:\n    src: \"{{ actk_src_tmp }}\/{{ actk_item }}\"\n    dest: \"{{ actk_dst_tmp }}\"\n  loop_control:\n    loop_var: actk_item\n  with_items: \"{{ actk_cert_list }}\"<\/code><\/pre>\n<p><\/p>\n<h3 id=\"den--311-uskoryaem-testy\">Giorno n. 311: Acceleriamo i test<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/ac7c16be6ea3e140916adc5b060286b7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Con il tempo, i test sono aumentati e i build sono diventati pi\u00f9 lenti, arrivando fino a un'ora in caso di problemi. In uno dei retro \u00e8 stata utilizzata un'espressione del tipo \"\u00e8 bello avere test, ma sono lenti\". Alla fine, abbiamo abbandonato i test di integrazione su macchine virtuali e ci siamo adattati a Docker per velocizzare il processo. Abbiamo anche sostituito testinfra con ansible verifier per ridurre il numero di strumenti utilizzati.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/58576edb7ce00491cd92d7bc6810fc93.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A rigor di termini, qui sono state adottate una serie di misure:<\/p>\n<p><\/p>\n<ol>\n<li>Passaggio a Docker.<\/li>\n<li>Eliminare il testing dei ruoli, che si duplicava a causa delle dipendenze.<\/li>\n<li>Aumentare il numero di slave.<\/li>\n<li>Ordine di esecuzione dei test.<\/li>\n<li>Possibilit\u00e0 di lintare <strong>TUTTO<\/strong> localmente con un solo comando.<\/li>\n<\/ol>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/3bcdaf0afc24c74739c852e220aa3b2d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Alla fine, il pipeline su Jenkins \u00e8 diventato unificato.<\/p>\n<p><\/p>\n<ol>\n<li>Generare fasi di build.<\/li>\n<li>Lintare tutto in parallelo.<\/li>\n<li>Esegui le fasi di test dei ruoli in parallelo.<\/li>\n<li>Finito.<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"lessons-learned\">Lezioni apprese<\/h2>\n<p><\/p>\n<h3 id=\"avoid-global-variables\">Evitare variabili globali<\/h3>\n<p><\/p>\n<p>Ansible utilizza variabili globali, esiste una parziale soluzione tramite <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ansible.com\/ansible\/latest\/reference_appendices\/config.html#default-private-role-vars\">private_role_vars<\/a><\/noindex>, ma non \u00e8 una panacea. <\/p>\n<p><\/p>\n<p>Far\u00f2 un esempio. Supponiamo di avere <code>role_a<\/code> e <code>role_b<\/code><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\"># cat role_a\/defaults\/main.yml\n---\nmsg: a\n\n# cat role_a\/tasks\/main.yml\n---\n- debug:\n    msg: role_a={{ msg }}<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\"># cat role_b\/defaults\/main.yml\n---\nmsg: b\n\n# cat role_b\/tasks\/main.yml\n---\n- set_fact:\n    msg: b\n- debug:\n    msg: role_b={{ msg }}<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: localhost\n  vars:\n    msg: hello\n  roles:\n    - role: role_a\n    - role: role_b\n  tasks:\n    - debug:\n        msg: play={{msg}}<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/7712ba529596ee00eaac22c9e59f7abe.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La cosa divertente \u00e8 che il risultato di esecuzione dei playbook dipender\u00e0 da fattori non sempre evidenti, come l'ordine delle dichiarazioni delle role. Sfortunatamente, questo \u00e8 nella natura di Ansible, e la cosa migliore che si pu\u00f2 fare \u00e8 utilizzare alcune convenzioni, come ad esempio utilizzare solo variabili definite all'interno della role.<\/p>\n<p><\/p>\n<p><strong>BAD<\/strong>: utilizzare una variabile globale.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\"># cat roles\/some_role\/tasks\/main.yml\n---\ndebug:\n  var: java_home<\/code><\/pre>\n<p><\/p>\n<p><strong>GOOD<\/strong>: In <code>defaults<\/code> definire le variabili necessarie e poi utilizzare solo quelle.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\"># cat roles\/some_role\/defaults\/main.yml\n---\nr__java_home:\n &quot;{{ java_home | default('\/path') }}&quot;\n\n# cat roles\/some_role\/tasks\/main.yml\n---\ndebug:\n  var: r__java_home\n<\/code><\/pre>\n<p><\/p>\n<h3 id=\"prefix-role-variables\">Prefix role variables<\/h3>\n<p><\/p>\n<p><strong>BAD<\/strong>: utilizzare una variabile globale.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\"># cat roles\/some_role\/defaults\/main.yml\n---\ndb_port: 5432<\/code><\/pre>\n<p><\/p>\n<p><strong>GOOD<\/strong>: Nella role, utilizzare variabili con un prefisso di nome della role rende pi\u00f9 facile comprendere cosa sta succedendo guardando l'inventario.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\"># cat roles\/some_role\/defaults\/main.yml\n---\nsome_role__db_port: 5432<\/code><\/pre>\n<p><\/p>\n<h3 id=\"use-loop-control-variable\">Use loop control variable<\/h3>\n<p><\/p>\n<p><strong>BAD<\/strong>: Utilizzare nella loops la variabile standard <code>item<\/code>, se questo task\/playbook fosse incluso altrove, potrebbe portare a comportamenti imprevisti.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n- hosts: localhost\n  tasks:\n    - debug:\n        msg: \"{{ item }}\"\n      loop:\n        - item1\n        - item2\n<\/code><\/pre>\n<p><\/p>\n<p><strong>GOOD<\/strong>: Ridefinire la variabile in un ciclo tramite <code>loop_var<\/code>.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n- hosts: localhost\n  tasks:\n    - debug:\n        msg: \"{{ item_name }}\"\n      loop:\n        - item1\n        - item2\n      loop_control:\n        loop_var: item_name\n<\/code><\/pre>\n<p><\/p>\n<h3 id=\"check-input-variables\">Verifica le variabili di input<\/h3>\n<p><\/p>\n<p>Abbiamo concordato di utilizzare i prefissi delle variabili; \u00e8 utile verificare che siano definiti come ci si aspetta e, ad esempio, non siano stati sovrascritti con un valore vuoto.<\/p>\n<p><\/p>\n<p><strong>GOOD<\/strong>: Controllare le variabili.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- name: \"Verifica che le variabili stringa richieste siano definite\"\n  assert:\n    that: ahs_var is defined and ahs_var | length &gt; 0 and ahs_var != None\n    fail_msg: \"{{ ahs_var }} deve essere impostato affinch\u00e9 il ruolo funzioni\"\n    success_msg: \"Le variabili richieste {{ ahs_var }} sono definite\"\n  loop_control:\n    loop_var: ahs_var\n  with_items:\n    - ahs_item1\n    - ahs_item2\n    - ahs_item3<\/code><\/pre>\n<p><\/p>\n<h3 id=\"avoid-hashes-dictionaries-use-flat-structure\">Evitare i dizionari hash, utilizzare una struttura piatta.<\/h3>\n<p><\/p>\n<p>Se il ruolo si aspetta un hash\/dizionario in uno dei parametri, se vogliamo modificare uno dei parametri secondari, dovremo ridefinire l'intero hash\/dizionario, il che aumenter\u00e0 la complessit\u00e0 della configurazione.<\/p>\n<p><\/p>\n<p><strong>BAD<\/strong>: Utilizzare hash\/dizionario.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\nuser:\n  name: admin\n  group: admin<\/code><\/pre>\n<p><\/p>\n<p><strong>GOOD<\/strong>: Utilizzare una struttura piatta per le variabili.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\nuser_name: admin\nuser_group: \"{{ user_name }}\"<\/code><\/pre>\n<p><\/p>\n<h3 id=\"create-idempotent-playbooks--roles\">Crea playbook e ruoli idempotenti.<\/h3>\n<p><\/p>\n<p>I ruoli e i playbook devono essere idempotenti poich\u00e9 riducono la deriva della configurazione e il timore di rompere qualcosa. Tuttavia, se si utilizza Molecule, questo comportamento \u00e8 predefinito.<\/p>\n<p><\/p>\n<h3 id=\"avoid-using-command-shell-modules\">Evitare l'uso dei moduli shell dei comandi.<\/h3>\n<p><\/p>\n<p>L'uso del modulo shell porta a una descrizione imperativa, invece di quella dichiarativa, che \u00e8 fondamentale per Ansible.<\/p>\n<p><\/p>\n<h3 id=\"test-your-roles-via-molecule\">Testa i tuoi ruoli tramite Molecule.<\/h3>\n<p><\/p>\n<p>Molecule \u00e8 uno strumento piuttosto flessibile; vediamo alcuni scenari.<\/p>\n<p><\/p>\n<h4 id=\"molecule-multiple-instances\">Molecule istanze multiple<\/h4>\n<p><\/p>\n<p>In <code>molecule.yml<\/code> nella sezione <code>piattaforme<\/code> \u00e8 possibile descrivere pi\u00f9 host da distribuire.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n    driver:\n      name: docker\n    platforms:\n      - name: postgresql-instance\n        hostname: postgresql-instance\n        image: registry.example.com\/postgres10:latest\n        pre_build_image: true\n        override_command: false\n        network_mode: host\n      - name: app-instance\n        hostname: app-instance\n        pre_build_image: true\n        image: registry.example.com\/docker_centos_ansible_tests\n        network_mode: host<\/code><\/pre>\n<p><\/p>\n<p>Di conseguenza, questi host possono essere poi usati in <code>converge.yml<\/code> utilizzare:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n- name: Convergere tutto\n  hosts: all\n  vars:\n    ansible_user: root\n  roles:\n    - role: some_role\n\n- name: Convergere db\n  hosts: db-instance\n  roles:\n    - role: some_db_role\n\n- name: Convergere app\n  hosts: app-instance\n  roles:\n    - role: some_app_role<\/code><\/pre>\n<p><\/p>\n<h4 id=\"ansible-verifier\">Verificatore Ansible<\/h4>\n<p><\/p>\n<p>In molecule c'\u00e8 la possibilit\u00e0 di utilizzare ansible per verificare che l'istanza sia stata configurata correttamente; inoltre, questo \u00e8 attivo di default dalla versione 3. Questo non \u00e8 flessibile come testinfra\/inspec, ma si possono verificare le aspettative relative al contenuto del file:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n- name: Verifica\n  hosts: all\n  tasks:\n    - name: copia configurazione\n      copy:\n        src: expected_standalone.conf\n        dest: \/root\/wildfly\/bin\/standalone.conf\n        mode: \"0644\"\n        owner: root\n        group: root\n      register: config_copy_result\n\n    - name: Certifica che standalone.conf sia cambiato\n      assert:\n        that: not config_copy_result.changed<\/code><\/pre>\n<p><\/p>\n<p>Oppure puoi avviare il servizio, attendere la sua disponibilit\u00e0 e effettuare un test di smoke:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n  - name: Verifica\n    hosts: solr\n    tasks:\n      - command: \/blah\/solr\/bin\/solr start -s \/solr_home -p 8983 -force\n      - uri:\n          url: http:\/\/127.0.0.1:8983\/solr\n          method: GET\n          status_code: 200\n        register: uri_result\n        until: uri_result is not failed\n        retries: 12\n        delay: 10\n      - name: Invia documenti a solr\n        command: \/blah\/solr\/bin\/post -c master \/exampledocs\/books.csv<\/code><\/pre>\n<p><\/p>\n<h3 id=\"put-complex-logic-into-modules--plugins\">Metti la logica complessa in moduli e plugin<\/h3>\n<p><\/p>\n<p>Ansible adotta un approccio dichiarativo, quindi quando effettui ramificazioni nel codice, trasformazioni dei dati o utilizzi moduli shell, il codice diventa difficile da leggere. Per affrontare questa complessit\u00e0 e mantenerlo comprensibile, non \u00e8 superfluo combattere contro di essa creando i propri moduli.<\/p>\n<p><\/p>\n<h3 id=\"summarize-tips--tricks\">Riepiloga suggerimenti e trucchi<\/h3>\n<p><\/p>\n<ol>\n<li>Evita le variabili globali.<\/li>\n<li>Aggiungi un prefisso alle variabili di ruolo.<\/li>\n<li>Usa variabili di controllo del ciclo.<\/li>\n<li>Controlla le variabili di input.<\/li>\n<li>Evita le strutture dizionario hash, usa una struttura piatta.<\/li>\n<li>Crea playbook e ruoli idempotenti.<\/li>\n<li>Evita di usare moduli di shell per i comandi.<\/li>\n<li>Testa i tuoi ruoli tramite molecule.<\/li>\n<li>Metti la logica complessa in moduli e plugin.<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"zaklyuchenie\">Conclusione<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non perdere la bussola.\" src=\"\/wp-content\/uploads\/2020\/05\/c52a13f6ba5500fce506fb0d448b496e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Non \u00e8 possibile semplicemente rifattorizzare l'infrastruttura di un progetto, anche se hai IaC. \u00c8 un processo lungo che richiede pazienza, tempo e conoscenze.<\/p>\n<p><\/p>\n<h2 id=\"links\">Links<\/h2>\n<p><\/p>\n<ul>\n<li>Diapositive <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.mail.ru\/public\/266x\/3hJ2mQBzf\">Come testare Ansible e non impazzire<\/a><\/noindex><\/li>\n<li>Video <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=GdrJv5oypfg\">Come testare Ansible e non impazzire<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/467171\">Cosa ho appreso testando 200.000 righe di codice infrastrutturale.<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/500040\/\">Ansible: Migrazione della configurazione di 120 VM da Coreos a Centos in 18 mesi<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/342216\/\">Come rompere biciclette sopra stampelle durante il test della propria distribuzione<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/437004\/\">Prova a testarmi se puoi, o i programmatori YML sognano di testare ansible?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ultral\/awesome-iac-testing\">Un elenco di articoli, conferenze e link fantastici sui test IaC<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/www.goncharov.xyz\/it\/ansible-testing-ru.html\">cross post<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/500226\/\">Versione in inglese<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<p><strong>UPD1 2020.05.01 20:30<\/strong> \u2014 Per la profilazione iniziale dei playbook \u00e8 possibile utilizzare <code>callback_whitelist = profile_tasks<\/code> per capire cosa sta impiegando pi\u00f9 tempo. Dopodich\u00e9, esaminiamo <noindex><a rel=\"nofollow\" href=\"https:\/\/shadow-soft.com\/turbo-charge-your-ansible\/\">la classica ottimizzazione di Ansible<\/a><\/noindex>. Si pu\u00f2 provare <noindex><a rel=\"nofollow\" href=\"https:\/\/mitogen.networkgenomics.com\/ansible_detailed.html\">mitogen<\/a><\/noindex><br \/>\n<strong>UPD2 2020.05.03 16:34<\/strong> \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/post\/500226\/\">Versione in inglese<\/a><\/noindex><\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/500058\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0430 DevOps-40 2020-03-18: \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f legacy, \u0442.\u043a. \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0434\u0443\u043c\u043a\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0443\u0440\u043e\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u042d\u0442\u043e \u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u043d\u0435 \u043f\u043b\u043e\u0445\u043e, \u044d\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043f\u043e\u0440\u0438\u0442\u044c \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0427\u0430\u0441\u0442\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433. \u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 Infrastructure as Code. \u0414\u0430 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u0430\u043a \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c Ansible \u0437\u0430 \u0433\u043e\u0434 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":80306,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-80305","post","type-post","status-publish","format-standard","has-post-thumbnail","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=\"\u042d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0430 DevOps-40 2020-03-18: \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f legacy, \u0442.\u043a. \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0434\u0443\u043c\u043a\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0443\u0440\u043e\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u042d\u0442\u043e \u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u043d\u0435 \u043f\u043b\u043e\u0445\u043e, \u044d\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043f\u043e\u0440\u0438\u0442\u044c \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0427\u0430\u0441\u0442\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433. \u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 Infrastructure as Code. \u0414\u0430 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u0430\u043a \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c Ansible \u0437\u0430 \u0433\u043e\u0434 \u0438\" \/>\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\/kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek\" \/>\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\u041a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Ansible, \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0437\u0430 \u0433\u043e\u0434 \u0438 \u043d\u0435 \u0441\u043b\u0435\u0442\u0435\u0442\u044c \u0441 \u043a\u0430\u0442\u0443\u0448\u0435\u043a | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0430 DevOps-40 2020-03-18: \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f legacy, \u0442.\u043a. \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0434\u0443\u043c\u043a\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0443\u0440\u043e\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u042d\u0442\u043e \u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u043d\u0435 \u043f\u043b\u043e\u0445\u043e, \u044d\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043f\u043e\u0440\u0438\u0442\u044c \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0427\u0430\u0441\u0442\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433. \u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 Infrastructure as Code. \u0414\u0430 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u0430\u043a \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c Ansible \u0437\u0430 \u0433\u043e\u0434 \u0438\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek\" \/>\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-05-04T23:42:50+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-04T23:42:50+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\udd47Come iniziare a testare Ansible, rifattorizzare un progetto in un anno e non impazzire | ProHoster","description":"Questa \u00e8 la trascrizione dell'intervento a DevOps-40 del 18 marzo 2020: A partire dal secondo commit, qualsiasi codice diventa legacy, poich\u00e9 le idee iniziali iniziano a divergere dalla dura realt\u00e0. Non \u00e8 n\u00e9 buono n\u00e9 cattivo, \u00e8 una realt\u00e0 con cui \u00e8 difficile discutere e bisogna convivere. Parte di questo processo \u00e8 il refactoring. Refactoring dell'Infrastructure as Code. Inizia la storia su come rifattorizzare Ansible in un anno e","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek","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\u041a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Ansible, \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0437\u0430 \u0433\u043e\u0434 \u0438 \u043d\u0435 \u0441\u043b\u0435\u0442\u0435\u0442\u044c \u0441 \u043a\u0430\u0442\u0443\u0448\u0435\u043a | ProHoster","og:description":"\u042d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0430 DevOps-40 2020-03-18: \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f legacy, \u0442.\u043a. \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0434\u0443\u043c\u043a\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0443\u0440\u043e\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u042d\u0442\u043e \u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u043d\u0435 \u043f\u043b\u043e\u0445\u043e, \u044d\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043f\u043e\u0440\u0438\u0442\u044c \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0427\u0430\u0441\u0442\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433. \u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 Infrastructure as Code. \u0414\u0430 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u0430\u043a \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c Ansible \u0437\u0430 \u0433\u043e\u0434 \u0438","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-nachat-testirovat-ansible-otrefaktorit-proekt-za-god-i-ne-sletet-s-katushek","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-05-04T23:42:50+00:00","article:modified_time":"2020-05-04T23:42:50+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"80305","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 16:20:41","updated":"2022-09-29 15:21:39"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/80305","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=80305"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/80305\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/80306"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=80305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=80305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=80305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}