{"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\/ro\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","title":{"rendered":"Principiile Ansible, f\u0103r\u0103 de care playbook-urile dumneavoastr\u0103 sunt ca un bulg\u0103re de paste lipite.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Fac multe recenzii pentru codul altora pe Ansible \u0219i scriu mult singur. \u00cen timpul analizei erorilor (at\u00e2t ale altora, c\u00e2t \u0219i ale mele), dar \u0219i a unor interviuri, am realizat gre\u0219eala fundamental\u0103 pe care o fac utilizatorii Ansible \u2014 se bazeaz\u0103 pe complexitate f\u0103r\u0103 a st\u0103p\u00e2ni bazele.<\/p>\n<p><\/p>\n<p>Pentru a corecta aceast\u0103 nedreptate universal\u0103, am decis s\u0103 scriu o introducere \u00een Ansible pentru cei care deja \u00eel cunosc. V\u0103 avertizez, aceasta nu este o reluare a manualelor, este un lung articol \u00een care sunt multe cuvinte \u0219i nu sunt imagini.<\/p>\n<p><\/p>\n<p>Nivelul a\u0219teptat al cititorului - a scris deja c\u00e2teva mii de linii YAML, a mai lucrat \u00een produc\u021bie, dar \"totul pare oarecum str\u00e2mb\".<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>Denomin\u0103ri<\/h1>\n<p><\/p>\n<p>Cea mai mare gre\u0219eal\u0103 a utilizatorului Ansible este c\u0103 nu \u0219tie cum se numesc lucrurile. Dac\u0103 nu \u0219tii denumirile, nu po\u021bi \u00een\u021belege ceea ce este scris \u00een documenta\u021bie. Un exemplu concret: la un interviu, o persoan\u0103, care p\u0103rea c\u0103 a scris mult pe Ansible, nu a putut r\u0103spunde la \u00eentrebarea \"din ce elemente const\u0103 un playbook?\". C\u00e2nd i-am sugerat c\u0103 \"a\u0219teptam r\u0103spunsul c\u0103 playbook-ul const\u0103 din play\", a urmat comentariul devastator \"noi nu folosim asta\". Oamenii scriu pe Ansible pentru bani \u0219i nu folosesc play. <em>De fapt, \u00eel folosesc, dar nu \u0219tiu ce este.<\/em><\/p>\n<p><\/p>\n<p>A\u0219adar, s\u0103 \u00eencepem cu simplu: cum se numesc lucrurile. Poate c\u0103 \u0219tiai asta, sau poate nu, pentru c\u0103 nu ai fost atent c\u00e2nd ai citit documenta\u021bia.<\/p>\n<p><\/p>\n<p>ansible-playbook execut\u0103 playbook. Playbook \u2014 este un fi\u0219ier cu extensia yml\/yaml, \u00een interiorul c\u0103ruia este ceva de genul:<\/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>Deja am \u00een\u021beles c\u0103 \u00eentregul acest fi\u0219ier este un playbook. Putem ar\u0103ta unde sunt rolurile (roles), unde sunt sarcinile (tasks). Dar unde este play-ul? \u0218i cu ce se deosebe\u0219te play de role sau playbook?<\/p>\n<p><\/p>\n<p>Totul este prezent \u00een documenta\u021bie. \u0218i este ignorat. \u00cencep\u0103torii - pentru c\u0103 exist\u0103 prea multe \u0219i nu po\u021bi re\u021bine totul imediat. Cei experimenta\u021bi - pentru c\u0103 sunt \"lucruri triviale\". Dac\u0103 e\u0219ti experimentat - recite\u0219te aceste pagini m\u0103car o dat\u0103 la \u0219ase luni, iar codul t\u0103u va deveni cu un nivel mai bun.<\/p>\n<p><\/p>\n<p>A\u0219adar, re\u021bine\u021bi: Playbook \u2014 este o list\u0103, format\u0103 din play \u0219i <code>import_playbook<\/code>.<br \/>\nAceasta este o play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group1\n  roles:\n    - role1<\/code><\/pre>\n<p><\/p>\n<p>\u0218i aceasta este o alt\u0103 play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group2,group3\n  tasks:\n    - debug:<\/code><\/pre>\n<p><\/p>\n<p>Ce este play? La ce folose\u0219te?<\/p>\n<p><\/p>\n<p>Play \u2014 este elementul cheie pentru playbook, pentru c\u0103 play \u0219i numai play leag\u0103 lista de roluri \u0219i\/sau sarcini de lista de gazde pe care trebuie s\u0103 fie executate. \u00cen ad\u00e2ncurile documenta\u021biei se poate g\u0103si o men\u021biune despre <code>delegate_to<\/code>, plugin-uri de c\u0103utare locale, set\u0103ri specifice pentru network-cli, jump hosts etc. Acestea permit o modificare minim\u0103 a locului de executare a sarcinilor. Dar, uita\u021bi de asta. Fiecare dintre aceste op\u021biuni avansate are aplica\u021bii foarte specifice \u0219i cu siguran\u021b\u0103 nu sunt universale. \u0218i noi vorbim despre elementele de baz\u0103 pe care ar trebui s\u0103 le cunoasc\u0103 \u0219i s\u0103 le foloseasc\u0103 to\u021bi.<\/p>\n<p><\/p>\n<p>Dac\u0103 vrei s\u0103 execu\u021bi \"ceva\" \"undeva\" - scrii un play. Nu o rol\u0103. Nu o rol\u0103 cu module \u0219i delega\u021bii. Prinzi \u0219i scrii play. \u00cen care, \u00een c\u00e2mpul hosts, enumeri unde se va executa, iar \u00een roles\/tasks - ce se va executa.<\/p>\n<p><\/p>\n<p>E simplu, nu? \u0218i cum altfel ar putea fi?<\/p>\n<p><\/p>\n<p>Unul dintre momentele caracteristice c\u00e2nd oamenii simt nevoia s\u0103 fac\u0103 asta f\u0103r\u0103 play este \"o rol\u0103 care configureaz\u0103 totul\". Vrei s\u0103 ai o rol\u0103 care s\u0103 configureze \u0219i <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/ro\/server\/dts-los-angeles\/\"   title=\"server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3633\">server<\/a> servere de tipul unu \u0219i servere de tipul doi.<\/p>\n<p><\/p>\n<p>Un exemplu arhetipal este monitorizarea. Se dore\u0219te un rol de monitorizare, care s\u0103 configureze monitorizarea. Rolul de monitorizare este atribuit hosturilor de monitorizare (\u00een cadrul play-ului corespunz\u0103tor). Dar, se dovede\u0219te c\u0103 pentru monitorizare trebuie s\u0103 instal\u0103m pachete pe hosturile pe care le monitoriz\u0103m. De ce s\u0103 nu folosim delegate? \u0218i, de asemenea, trebuie s\u0103 configur\u0103m iptables. delegate? \u0218i, de asemenea, trebuie s\u0103 scriem\/corect\u0103m configura\u021bia pentru SGBD, astfel \u00eenc\u00e2t monitorizarea s\u0103 fie permis\u0103. delegate! \u0218i dac\u0103 inspira\u021bia vine, atunci putem face delega\u021bie <code>include_role<\/code> \u00eentr-un ciclu interior printr-un filtru inteligent pe lista grupurilor, iar \u00een interior <code>include_role<\/code> putem face \u0219i <code>delegate_to<\/code> din nou. \u0218i a \u00eenceput...<\/p>\n<p><\/p>\n<p>O dorin\u021b\u0103 nobil\u0103 - a avea o singur\u0103 rol\u0103 de monitorizare care \"face totul\" - ne duce \u00eentr-un iad de negru din care, cel mai adesea, exist\u0103 o singur\u0103 ie\u0219ire: a scrie totul de la zero.<\/p>\n<p><\/p>\n<p>Unde a intervenit gre\u0219eala? \u00cen momentul \u00een care ai descoperit c\u0103 pentru a finaliza sarcina \"x\" pe hostul X trebuie s\u0103 te duci pe hostul Y \u0219i s\u0103 faci acolo \"y\", ar fi trebuit s\u0103 faci un exerci\u021biu simplu: s\u0103 te duci \u0219i s\u0103 scrii un play care pe hostul Y face y. Nu s\u0103 adaugi ceva \u00een \"x\", ci s\u0103 scrii de la zero. Chiar \u0219i cu variabile hardcodate.<\/p>\n<p><\/p>\n<p>Pare c\u0103 \u00een paragrafele de mai sus totul este spus corect. Dar aceasta nu este situa\u021bia dvs.! Deoarece dori\u021bi s\u0103 scrie\u021bi cod reutilizabil, care s\u0103 fie DRY \u0219i s\u0103 semene cu o bibliotec\u0103, \u0219i trebuie s\u0103 c\u0103uta\u021bi metoda de a face acest lucru.<\/p>\n<p><\/p>\n<p>Aici s-a ascuns o alt\u0103 gre\u0219eal\u0103 grav\u0103. O gre\u0219eal\u0103 care a transformat numeroase proiecte din scrise rezonabil (se putea mai bine, dar totul func\u021bioneaz\u0103 \u0219i poate fi continuat u\u0219or) \u00eentr-un co\u0219mar complet, \u00een care chiar \u0219i autorul nu se mai poate descurca. Func\u021bioneaz\u0103, dar Dumnezeule fere\u0219te s\u0103 schimb ceva.<\/p>\n<p><\/p>\n<p>Aceast\u0103 gre\u0219eal\u0103 sun\u0103 astfel: rolul este o func\u021bie de bibliotec\u0103. Aceast\u0103 analogie a distrus at\u00e2t de multe ini\u021biative bune, \u00eenc\u00e2t este pur \u0219i simplu trist s\u0103 ne uit\u0103m. Rolul nu este o func\u021bie de bibliotec\u0103. Nu poate face calcule \u0219i nu poate lua decizii la nivel de play. Aminte\u0219te-mi, ce decizii ia play?<\/p>\n<p><\/p>\n<p>Mul\u021bumesc, ai dreptate. Play ia decizia (mai exact, con\u021bine informa\u021bia) despre ce sarcini \u0219i roluri s\u0103 fie executate pe ce gazde.<\/p>\n<p><\/p>\n<p>Dac\u0103 delegi aceast\u0103 decizie unui rol, \u0219i \u00eenc\u0103 cu calcule, te condamni (pe tine \u0219i pe cel care va \u00eencerca s\u0103 \u00een\u021beleag\u0103 codul t\u0103u) la o existen\u021b\u0103 jalnic\u0103. Rolul nu decide unde s\u0103 se execute. Aceast\u0103 decizie o ia play. Rolul face ceea ce i s-a spus, acolo unde i s-a spus.<\/p>\n<p><\/p>\n<p>De ce programarea \u00een Ansible este periculoas\u0103 \u0219i de ce COBOL este mai bun dec\u00e2t Ansible vom discuta \u00een capitolul despre variabile \u0219i jinja. P\u00e2n\u0103 atunci s\u0103 spunem un lucru - fiecare calcul al t\u0103u las\u0103 \u00een urm\u0103 o amprent\u0103 indestructibil\u0103 a modific\u0103rii variabilelor globale, \u0219i nu po\u021bi face nimic \u00een leg\u0103tur\u0103 cu asta. De \u00eendat\u0103 ce dou\u0103 \"amprente\" s-au intersectat - totul s-a pierdut.<\/p>\n<p><\/p>\n<p>Observa\u021bie pentru cei aten\u021bi: rolul poate influen\u021ba, desigur, fluxul de control. Exist\u0103 <code>delegate_to<\/code> \u0219i are aplica\u021bii rezonabile. Exist\u0103 <code>meta: end host\/play<\/code>. Dar! Aminti\u021bi-v\u0103, \u00eenv\u0103\u021b\u0103m no\u021biunile de baz\u0103? A\u021bi uitat despre <code>delegate_to<\/code>. Vorbim despre cel mai simplu \u0219i frumos cod \u00een Ansible. Care este u\u0219or de citit, u\u0219or de scris, u\u0219or de debuggat, u\u0219or de testat \u0219i u\u0219or de continuat. A\u0219adar, \u00eenc\u0103 o dat\u0103:<\/p>\n<p><\/p>\n<p><strong>play \u0219i doar play decide pe ce gazde se execut\u0103 ce.<\/strong><\/p>\n<p><\/p>\n<p>\u00cen aceast\u0103 sec\u021biune am discutat despre opozi\u021bia dintre play \u0219i rol. Acum s\u0103 vorbim despre rela\u021bia sarcini vs rol.<\/p>\n<p><\/p>\n<h1>Sarcini \u0219i Roluri<\/h1>\n<p><\/p>\n<p>S\u0103 lu\u0103m \u00een considerare 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>S\u0103 presupunem c\u0103 trebuie s\u0103 faci foo. \u0218i arat\u0103 a\u0219a <code>foo: name=foobar state=present<\/code>. Unde trebuie s\u0103 scrii asta? \u00een pre? post? S\u0103 creezi un rol?<\/p>\n<p><\/p>\n<p>\u2026 \u0218i unde au disp\u0103rut sarcinile?<\/p>\n<p><\/p>\n<p>Revenim la bazele jocului \u2014 dispozitivul play. Dac\u0103 nu cuno\u0219ti acest subiect, nu po\u021bi folosi play ca baz\u0103 pentru tot restul, iar rezultatul t\u0103u va fi unul \u201e\u00eenc\u00e2lcit\u201d.<\/p>\n<p><\/p>\n<p>Dispozitivul play: directiva hosts, set\u0103rile play-ului \u00een sine \u0219i sec\u021biunile pre_tasks, tasks, roles, post_tasks. Celelalte parametri pentru play nu sunt importante acum.<\/p>\n<p><\/p>\n<p>Ordinea sec\u021biunilor lor cu sarcini \u0219i roluri: <code>pre_tasks<\/code>, <code>roles<\/code>, <code>tasks<\/code>, <code>post_tasks<\/code>. Deoarece nu este clar ordinea de execu\u021bie \u00eentre <code>tasks<\/code> \u0219i <code>roles<\/code> best practices ne spun c\u0103 ad\u0103ug\u0103m sec\u021biunea <code>tasks<\/code>, numai dac\u0103 nu exist\u0103 <code>roles<\/code>. Dac\u0103 exist\u0103 <code>roles<\/code>, atunci toate sarcinile ata\u0219ate sunt plasate \u00een sec\u021biunile <code>pre_tasks<\/code>\/<code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>R\u0103m\u00e2ne doar ceea ce este clar semnificativ: mai \u00eent\u00e2i <code>pre_tasks<\/code>, apoi <code>roles<\/code>, apoi <code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>Dar \u00eenc\u0103 nu am r\u0103spuns la \u00eentrebarea: unde s\u0103 scriem apelul modulului <code>foo<\/code> ? Trebuie s\u0103 scriem un rol \u00eentreg pentru fiecare modul? Sau este mai bine s\u0103 avem un rol complex pentru toate? \u0218i dac\u0103 nu este rol, unde s\u0103 scriem \u2013 \u00een pre sau \u00een post?<\/p>\n<p><\/p>\n<p>Dac\u0103 nu exist\u0103 un r\u0103spuns argumentat la aceste \u00eentreb\u0103ri, acesta este un semn al lipsei de intui\u021bie, adic\u0103 acele \u201ebaze \u0219ubrede\u201d. Hai s\u0103 clarific\u0103m. \u00cencepe cu \u00eentrebarea de control: Dac\u0103 play are <code>pre_tasks<\/code> \u0219i <code>post_tasks<\/code> (\u0219i nu exist\u0103 sarcini, nici roluri), se poate \u00eent\u00e2mpla ceva r\u0103u dac\u0103 mut greaua sarcin\u0103 din <code>post_tasks<\/code> la finalul <code>pre_tasks<\/code>?<\/p>\n<p><\/p>\n<p>Desigur, formularea \u00eentreb\u0103rii sugereaz\u0103 c\u0103 se va strica ceva. Dar ce anume?<\/p>\n<p><\/p>\n<p>\u2026 Handleri. Studiul bazelor dezv\u0103luie un fapt important: toate handler-urile se executeaz\u0103 automat dup\u0103 fiecare sec\u021biune. Adic\u0103 toate sarcinile din <code>pre_tasks<\/code>, apoi toate manevrele care au fost notify. Apoi se execut\u0103 toate rolurile \u0219i toate manevrele care au fost notify \u00een roluri. Apoi <code>post_tasks<\/code> \u0219i manevrele lor.<\/p>\n<p><\/p>\n<p>Astfel, dac\u0103 mu\u021bi o sarcin\u0103 din <code>post_tasks<\/code> \u00een <code>pre_tasks<\/code>, a\u0219adar, poten\u021bial, o vei executa \u00eenainte de a executa handler-ul. De exemplu, dac\u0103 \u00een <code>pre_tasks<\/code> se instaleaz\u0103 \u0219i se configureaz\u0103 <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/ro\/server\/\"   title=\"server web\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1155\">server web<\/a>, iar \u00een <code>post_tasks<\/code> se trimite ceva, atunci mutarea acestei sarcini \u00een sec\u021biunea <code>pre_tasks<\/code> va duce la faptul c\u0103 \u00een momentul \u201etrimiterii\u201d serverul nu va fi \u00eenc\u0103 pornit \u0219i totul se va strica.<\/p>\n<p><\/p>\n<p>Acum s\u0103 ne g\u00e2ndim din nou, de ce avem nevoie de <code>pre_tasks<\/code> \u0219i <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> ne va permite s\u0103 lucr\u0103m cu rezultatele execu\u021biei rolurilor (inclusiv manevrele).<\/p>\n<p><\/p>\n<p>Un cunosc\u0103tor perspicace al Ansible ne va spune c\u0103 exist\u0103 <code>meta: flush_handlers<\/code>, dar de ce avem nevoie de flush_handlers, dac\u0103 ne putem baza pe ordinea de execu\u021bie a sec\u021biunilor \u00een play? Mai mult, utilizarea meta: flush_handlers poate provoca apari\u021bia nea\u0219teptat\u0103 a manevrelor repetate, gener\u00e2nd avertismente ciudate \u00een cazul utiliz\u0103rii <code>when<\/code> u <code>block<\/code> \u0219i a\u0219a mai departe. Cu c\u00e2t \u0219tii mai bine Ansible, cu at\u00e2t mai multe nuan\u021be po\u021bi numi pentru o solu\u021bie \u201einteligent\u0103\u201d. O solu\u021bie simpl\u0103 \u2014 utilizarea unei separ\u0103ri naturale \u00eentre pre\/roles\/post \u2014 nu genereaz\u0103 nuan\u021be.<\/p>\n<p><\/p>\n<p>\u0218i, revenind la \u201efoo\u201d-ul nostru. Unde ar trebui s\u0103-l plas\u0103m? \u00cen pre, post sau \u00een roles? Evident, depinde de necesitatea rezultatelor lucrului handler-ului pentru foo. Dac\u0103 nu exist\u0103, atunci foo nu trebuie plasat nici \u00een pre, nici \u00een post \u2014 aceste sec\u021biuni au un sens special \u2014 executarea sarcinilor \u00eenainte \u0219i dup\u0103 array-ul principal de cod.<\/p>\n<p><\/p>\n<p>Acum r\u0103spunsul la \u00eentrebarea \u201erol sau sarcin\u0103\u201d se reduce la ceea ce exist\u0103 deja \u00een play \u2014 dac\u0103 exist\u0103 tasks, atunci trebuie s\u0103 scriem \u00een tasks. Dac\u0103 exist\u0103 roles \u2014 trebuie s\u0103 cre\u0103m un rol (chiar \u0219i dintr-o singur\u0103 task). \u00ce\u021bi reamintesc, tasks \u0219i roles nu sunt utilizate simultan.<\/p>\n<p><\/p>\n<p>\u00cen\u021belegerea elementelor de baz\u0103 ale Ansible ofer\u0103 r\u0103spunsuri motivate la \u00eentreb\u0103ri ce p\u0103reau subiective.<\/p>\n<p><\/p>\n<h1>Sarcini \u0219i roluri (partea a doua)<\/h1>\n<p><\/p>\n<p>Acum s\u0103 discut\u0103m despre situa\u021bia \u00een care abia \u00eencepi s\u0103 scrii un playbook. Trebuie s\u0103 faci foo, bar \u0219i baz. Sunt acestea trei sarcini, un rol sau trei roluri? Generaliz\u00e2nd \u00eentrebarea: c\u00e2nd trebuie s\u0103 \u00eencepi s\u0103 scrii roluri? Care este sensul scrierii rolurilor, c\u00e2nd po\u021bi scrie sarcini?\u2026 \u0218i ce este un rol?<\/p>\n<p><\/p>\n<p>Una dintre cele mai grave gre\u0219eli (deja am men\u021bionat asta) este s\u0103 consideri c\u0103 un rol este ca o func\u021bie \u00eentr-o bibliotec\u0103 a unei aplica\u021bii. Cum arat\u0103 o descriere generalizat\u0103 a unei func\u021bii? Accept\u0103 argumente la intrare, interac\u021bioneaz\u0103 cu efecte secundare, produce efecte secundare, returneaz\u0103 o valoare.<\/p>\n<p><\/p>\n<p>Acum, aten\u021bie. Ce dintre acestea poate fi realizat \u00eentr-un rol? A provoca efecte secundare \u2014 \u00eentotdeauna, este esen\u021ba \u00eentregului Ansible \u2014 a provoca efecte secundare. A avea cauze secundare? Elementar. Dar \u00een ceea ce prive\u0219te \u201ea transmite o valoare \u0219i a o returna\u201d \u2014 aici e problema. \u00cen primul r\u00e2nd, nu po\u021bi transmite o valoare \u00eentr-un rol. Po\u021bi seta o variabil\u0103 global\u0103 cu o durat\u0103 de via\u021b\u0103 de dimensiunea play-ului \u00een sec\u021biunea vars pentru rol. Po\u021bi seta o variabil\u0103 global\u0103 cu o durat\u0103 de via\u021b\u0103 \u00een play \u00een interiorul rolului. Sau chiar cu o durat\u0103 de via\u021b\u0103 de playbook (<code>set_fact<\/code>\/<code>register<\/code>). Dar nu po\u021bi avea \u201evariabile locale\u201d. Nu po\u021bi \u201eaccepta o valoare\u201d \u0219i \u201ereturna una\u201d.<\/p>\n<p><\/p>\n<p>Din aceasta rezult\u0103 concluzia principal\u0103: nu po\u021bi scrie nimic \u00een Ansible f\u0103r\u0103 a provoca efecte secundare. Schimbarea variabilelor globale este \u00eentotdeauna un efect secundar pentru func\u021bie. \u00cen Rust, de exemplu, schimbarea unei variabile globale este <code>unsafe<\/code>. \u00cen Ansible, metoda unic\u0103 de a influen\u021ba valorile pentru rol este esen\u021bial\u0103. Observa\u021bi cuvintele folosite: nu \u201etransmite\u021bi o valoare \u00een rol\u201d, ci \u201eschimba\u021bi valorile pe care le utilizeaz\u0103 rolul\u201d. Nu exist\u0103 izolare \u00eentre roluri. Nu exist\u0103 izolare \u00eentre sarcini \u0219i roluri.<\/p>\n<p><\/p>\n<p>\u00cen total: <strong>rolul este nu o func\u021bie<\/strong>.<\/p>\n<p><\/p>\n<p>Ce este bun \u00een rol? \u00cen primul r\u00e2nd, rolul are valori implicite (<code>\/default\/main.yaml<\/code>), \u00een al doilea r\u00e2nd rolul are directoare suplimentare pentru stocarea fi\u0219ierelor.<\/p>\n<p><\/p>\n<p>Ce este at\u00e2t de bun la valorile implicite? C\u0103 \u00een piramida lui Maslow, o tabel\u0103 destul de distorsionat\u0103 de priorit\u0103\u021bi a variabilelor \u00een Ansible, valorile implicite ale rolului sunt cele mai pu\u021bin prioritizate (cu excep\u021bia parametrilor din linia de comand\u0103 Ansible). Aceasta \u00eenseamn\u0103 c\u0103, dac\u0103 trebuie s\u0103 oferi\u021bi valori implicite f\u0103r\u0103 a v\u0103 face griji c\u0103 ele vor suprascrie valorile din inventar sau din variabilele de grup, atunci valorile implicite ale rolului sunt singurul loc corect pentru dvs. (M\u0103 mint pu\u021bin - mai exist\u0103 \u0219i <code>|d(your_default_here)<\/code>, dar dac\u0103 vorbim despre locuri statice - atunci doar valorile implicite ale rolurilor).<\/p>\n<p><\/p>\n<p>Ce altceva este bun \u00een roluri? C\u0103 acestea au directoarele lor. Acestea sunt directoare pentru variabile, at\u00e2t permanente (adic\u0103, calculate pentru rol), c\u00e2t \u0219i pentru cele dinamice (exist\u0103 un tip de model sau anti-model - <code>include_vars<\/code> \u00eempreun\u0103 cu <code>{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml<\/code>.). Acestea sunt directoare pentru <code>files\/<\/code>, <code>templates\/. De asemenea, permite rolurilor s\u0103 aib\u0103 module \u0219i pluginuri proprii (<\/code>library\/<code>). Dar, \u00een compara\u021bie cu sarcinile din playbook-uri (care pot avea \u0219i toate acestea), beneficiul const\u0103 doar \u00een faptul c\u0103 fi\u0219ierele sunt grupate nu \u00eentr-un singur loc, ci \u00een mai multe gr\u0103mezi separate.<\/code>). \u00cens\u0103, comparativ cu sarcinile din playbook (care poate avea toate acestea), beneficiul este doar faptul c\u0103 fi\u0219ierele sunt organizate \u00een grupuri separate, nu amestecate \u00eentr-un singur loc.<\/p>\n<p><\/p>\n<p>Astfel, rolurile au dou\u0103 caracteristici importante: au valori implicite (o caracteristic\u0103 unic\u0103) \u0219i permit structurarea codului.<\/p>\n<p><\/p>\n<p>Revenind la \u00eentrebarea ini\u021bial\u0103: c\u00e2nd s\u0103 faci sarcini \u0219i c\u00e2nd s\u0103 folose\u0219ti roluri? Sarcinile \u00een playbook sunt folosite cel mai adesea fie ca \"lipici\" \u00eenainte\/dup\u0103 roluri, fie ca un element de construc\u021bie de sine st\u0103t\u0103tor (atunci codul nu ar trebui s\u0103 con\u021bin\u0103 roluri). O gr\u0103mad\u0103 de sarcini normale amestecate cu roluri - aceasta este cu siguran\u021b\u0103 neglijen\u021b\u0103. Ar trebui s\u0103 te \u021bii de un stil specific \u2013 fie sarcini, fie roluri. Rolurile ofer\u0103 separarea entit\u0103\u021bilor \u0219i valorile implicite, sarcinile permit citirea mai rapid\u0103 a codului. De obicei, \u00een roluri sunt extrase coduri mai \"statice\" (importante \u0219i complexe), iar \u00een stilul sarcinilor se scriu scripturi auxiliare.<\/p>\n<p><\/p>\n<p>Revenind la \u00eentrebarea ini\u021bial\u0103: c\u00e2nd s\u0103 folosi\u021bi sarcini \u0219i c\u00e2nd roluri? Sarcinile din playbook sunt cel mai adesea utilizate fie ca \u201elipici\u201d \u00eenainte\/sesiune dup\u0103 roluri, fie ca elemente de construc\u021bie independente (atunci codul nu ar trebui s\u0103 con\u021bin\u0103 roluri). Un amestec de sarcini normale cu roluri este cu siguran\u021b\u0103 o neglijen\u021b\u0103. Trebuie s\u0103 respecta\u021bi un stil specific \u2014 fie sarcini, fie roluri. Rolurile ofer\u0103 separarea entit\u0103\u021bilor \u0219i valori implicite, iar sarcinile permit citirea codului mai rapid. De obicei, \u00een roluri se mut\u0103 codul mai \u201esta\u021bionar\u201d (important \u0219i complex), iar \u00een stilul sarcinilor se scriu scripturi auxiliare.<\/p>\n<p><\/p>\n<p>Exist\u0103 posibilitatea de a face import_role ca o sarcin\u0103, dar dac\u0103 scrie\u021bi a\u0219a ceva, fi\u021bi preg\u0103tit s\u0103 explica\u021bi propriul sentiment estetic despre motivul pentru care dori\u021bi s\u0103 face\u021bi asta.<\/p>\n<p><\/p>\n<p>Un cititor perspicace ar putea spune c\u0103 rolurile pot importa roluri, rolurile pot avea dependen\u021be prin galaxy.yml, \u0219i mai este un lucru \u00eenfrico\u0219\u0103tor \u0219i terifiant. <code>include_role<\/code> \u2014 \u00eemi amintesc, ne \u00eembun\u0103t\u0103\u021bim abilit\u0103\u021bile \u00een Ansible de baz\u0103, nu \u00een gimnastic\u0103 ritmic\u0103.<\/p>\n<p><\/p>\n<h1>Handleri \u0219i sarcini<\/h1>\n<p><\/p>\n<p>S\u0103 discut\u0103m despre un alt lucru evident: handlerii. Capacitatea de a-i folosi corect este aproape o art\u0103. Care este diferen\u021ba \u00eentre un handler \u0219i o sarcin\u0103?<\/p>\n<p><\/p>\n<p>A\u0219a c\u0103, av\u00e2nd \u00een vedere c\u0103 ne amintim de bazele, iat\u0103 un exemplu:<\/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>\u00cen roluri, handler-ii se afl\u0103 \u00een rolename\/handlers\/main.yaml. Handler-ii sunt partaja\u021bi \u00eentre to\u021bi participan\u021bii la play: pre\/post_tasks pot apela handler-ii rolului, iar rolul poate apela handler-ii din play. Cu toate acestea, apelurile de handler-i \u201e\u00eencruci\u0219a\u021bi\u201d genereaz\u0103 mult mai mult confuzie dec\u00e2t repetarea unui handler trivial. (Un alt element al celor mai bune practici \u2014 \u00eencerca\u021bi s\u0103 evita\u021bi repetarea numelui handler-ilor).<\/p>\n<p><\/p>\n<p>Principala diferen\u021b\u0103 este c\u0103 o sarcin\u0103 se execut\u0103 (idempotent) \u00eentotdeauna (plus\/minus etichete \u0219i <code>when<\/code>), \u00een timp ce handlerul se declan\u0219eaz\u0103 \u00een func\u021bie de schimbarea st\u0103rii (notify se activeaz\u0103 doar dac\u0103 a fost modificat). Ce \u00eenseamn\u0103 asta? De exemplu, c\u0103 la o nou\u0103 rulare, dac\u0103 nu a fost modificat, nu va fi nici handler. \u0218i de ce ar putea fi necesar s\u0103 execut\u0103m handlerul c\u00e2nd nu a fost modificat la sarcina generatoare? De exemplu, pentru c\u0103 ceva s-a stricat \u0219i a fost modificat, dar execu\u021bia nu a ajuns la handler. De exemplu, din cauza c\u0103 re\u021beaua a c\u0103zut temporar. Configura\u021bia s-a schimbat, dar serviciul nu a fost repornit. La urm\u0103toarea rulare, configura\u021bia nu mai este schimbat\u0103 \u0219i serviciul r\u0103m\u00e2ne cu vechea versiune a configura\u021biei.<\/p>\n<p><\/p>\n<p>Situa\u021bia cu configura\u021bia este neregenerabil\u0103 (mai exact, pute\u021bi inventa un prototip special de repornire cu fi\u0219iere de semnalizare etc., dar aceasta nu mai este 'ansible de baz\u0103' \u00een niciun fel). Totu\u0219i, exist\u0103 o alt\u0103 poveste frecvent\u0103: am instalat aplica\u021bia, am \u00eenregistrat-o. <code>.service<\/code>-fi\u0219ier \u0219i acum vrem s\u0103-i facem <code>daemon_reload<\/code> \u0219i <code>state=started<\/code>. \u0218i un loc natural pentru asta pare a fi handler-ul. Dar dac\u0103 \u00eel transform\u0103m \u00eentr-o task la sf\u00e2r\u0219itul listei de task-uri sau rolului, atunci acesta va fi executat idempotent de fiecare dat\u0103. Chiar \u0219i dac\u0103 playbook-ul se \u00eentrerupe pe parcurs. Aceasta nu rezolv\u0103 deloc problema restarted (nu putem face o task cu atributul restarted, deoarece se pierde idempotenta), dar este clar c\u0103 ar trebui s\u0103 folosim state=started, stabilitatea general\u0103 a playbook-urilor cre\u0219te, deoarece se reduce num\u0103rul de conexiuni \u0219i de st\u0103ri dinamice.<\/p>\n<p><\/p>\n<p>Un alt aspect pozitiv al handler-ului este c\u0103 nu aglomereaz\u0103 ie\u0219irea. Nu au fost modific\u0103ri \u2014 nu exist\u0103 mesaje suplimentare skipped sau ok \u00een ie\u0219ire \u2014 mai u\u0219or de citit. Acesta este, de asemenea, un dezavantaj \u2014 dac\u0103 g\u0103si\u021bi o gre\u0219eal\u0103 \u00eentr-o sarcin\u0103 executat\u0103 liniar la prima rulare, handler-ii vor fi executa\u021bi doar la changed, adic\u0103 \u00een anumite condi\u021bii \u2014 foarte rar. De exemplu, prima dat\u0103 \u00een via\u021b\u0103 dup\u0103 cinci ani. \u0218i, desigur, acolo va fi o gre\u0219eal\u0103 \u00een nume \u0219i totul se va strica. Iar a doua oar\u0103 nu le pute\u021bi rula \u2014 c\u0103ci nu este changed.<\/p>\n<p><\/p>\n<p>Este important s\u0103 discut\u0103m despre accesibilitatea variabilelor. De exemplu, dac\u0103 folosi\u021bi notify pentru o task cu ciclu, ce va fi \u00een variabile? Se poate deduce analitic, dar nu este \u00eentotdeauna trivial, mai ales dac\u0103 variabilele provin din locuri diferite.<\/p>\n<p><\/p>\n<p>\u2026 A\u0219adar, handler-ii sunt mult mai pu\u021bin utili \u0219i mult mai problematici dec\u00e2t par. Dac\u0103 se poate scrie ceva frumos (f\u0103r\u0103 \u00eendoielnic) f\u0103r\u0103 handlers, mai bine este s\u0103 se fac\u0103 f\u0103r\u0103 ei. Dac\u0103 nu reu\u0219e\u0219ti s\u0103 scrii frumos \u2014 mai bine cu ei.<\/p>\n<p><\/p>\n<p>Citiatorul perseveren\u021b \u00ee\u0219i face o observa\u021bie corect\u0103, c\u0103 nu am discutat <code>listen<\/code>, c\u0103 handler-ul poate apela notify pentru un alt handler, c\u0103 handler-ul poate include import_tasks (care poate face include_role cu with_items), c\u0103 sistemul de handlers din Ansible este turing-complet, c\u0103 handler-ii din include_role se intersecteaz\u0103 \u00een mod interesant cu handler-ii din play etc. \u2014 toate acestea cu siguran\u021b\u0103 nu sunt \"fundamente\").<\/p>\n<p><\/p>\n<p>De\u0219i exist\u0103 un anumit WTF specific, care este de fapt o caracteristic\u0103 \u0219i de care trebuie s\u0103 \u021bine\u021bi cont. Dac\u0103 task-ul dvs. se execut\u0103 cu <code>delegate_to<\/code> \u0219i are un notify, atunci handler-ul corespunz\u0103tor se execut\u0103 f\u0103r\u0103 <code>delegate_to<\/code>, adic\u0103 pe hostul pe care este asignat play-ul. (De\u0219i handler-ul, desigur, poate avea <code>delegate_to<\/code> de asemenea).<\/p>\n<p><\/p>\n<p>\u00cen mod separat, vreau s\u0103 spun c\u00e2teva cuvinte despre roluri reutilizabile. P\u00e2n\u0103 la apari\u021bia colec\u021biilor, exista ideea de a crea roluri universale, care se pot <code>ansible-galaxy install<\/code> \u0218i am plecat. Func\u021bioneaz\u0103 pe toate sistemele de operare \u00een toate variantele, \u00een toate situa\u021biile. A\u0219adar, opinia mea este: nu func\u021bioneaz\u0103. Orice rol cu suport pentru 100500 de cazuri este sortit s\u0103 se confrunte cu abisurile bug-urilor corner case. Acestea pot fi remediate prin teste extenuante, dar, la fel ca \u00een orice testare, fie ave\u021bi un produs cartezian de valori de intrare \u0219i o func\u021bie total\u0103, fie ave\u021bi \"scenarii individuale acoperite\". Cred c\u0103 este cu mult mai bine dac\u0103 rolul este liniar (complexitate ciclomatic\u0103 1). <code>include_vars<\/code>, sus\u021binerea a 100500 de cazuri este condamnat\u0103 la abisuri de bug-uri corner case. Acestea pot fi acoperite prin testare masiv\u0103, dar ca \u00een orice testare, ori ave\u021bi produsul cartezian al valorilor de intrare \u0219i o func\u021bie total\u0103, ori ave\u021bi \"cazuri specifice acoperite\". P\u0103rerea mea \u2014 este mult mai bine dac\u0103 rolul este liniar (complexitatea ciclomatic\u0103 1).<\/p>\n<p><\/p>\n<p>Cu c\u00e2t mai pu\u021bine if-uri (exprimat sau declarativ \u2014 \u00een forma <code>when<\/code> sau form\u0103 <code>include_vars<\/code> \u00een func\u021bie de setul de variabile), cu at\u00e2t mai bine este rolul. Uneori trebuie s\u0103 facem ramifica\u021bii, dar, repet, cu c\u00e2t mai pu\u021bine sunt, cu at\u00e2t mai bine. A\u0219adar, o rol bun cu galaxy (func\u021bioneaz\u0103 dup\u0103 toate!) cu o mul\u021bime de <code>when<\/code> poate fi mai pu\u021bin preferabil\u0103 dec\u00e2t \"rolul s\u0103u\" din cinci task-uri. Momentul \u00een care rolul cu galaxy este mai bun \u2014 este c\u00e2nd \u00eencepe\u021bi s\u0103 scrie\u021bi ceva. Momentul \u00een care devine mai r\u0103u \u2014 este c\u00e2nd ceva se stric\u0103 \u0219i ave\u021bi suspiciuni c\u0103 aceasta se datoreaz\u0103 \"rolului cu galaxy\". \u00cel deschide\u021bi \u0219i g\u0103si\u021bi cinci includes, opt liste de task-uri \u0219i un teanc <code>when<\/code>\u2026 \u0218i trebuie s\u0103 v\u0103 ocupa\u021bi de asta. \u00cen loc de 5 task-uri \u00eentr-o list\u0103 liniar\u0103, \u00een care nu am ce s\u0103 se strice.<\/p>\n<p><\/p>\n<h1>\u00cen p\u0103r\u021bile urm\u0103toare<\/h1>\n<p><\/p>\n<ul>\n<li>Un pic despre inventar, variabilele de grup, pluginul host_group_vars, hostvars. Cum s\u0103 legi un nod gordian din spaghete. Domeniul \u0219i preceden\u021ba variabilelor, modelul de memorie Ansible. \"Deci, unde ar trebui s\u0103 stochez numele utilizatorului pentru baza de date?\".<\/li>\n<li><code>jinja: {{ jinja }}<\/code> \u2014 nosql notype nosense plastic moale. Este peste tot, chiar \u0219i acolo unde nu te a\u0219tep\u021bi. Pu\u021bin despre <code>!!unsafe<\/code> \u0219i yaml delicios.<\/li>\n<\/ul>\n<p>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/508762\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c. \u0412 \u0445\u043e\u0434\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043e\u0448\u0438\u0431\u043e\u043a (\u043a\u0430\u043a \u0447\u0443\u0436\u0438\u0445, \u0442\u0430\u043a \u0438 \u0441\u0432\u043e\u0438\u0445), \u0430 \u0442\u0430\u043a \u0436\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439, \u044f \u043f\u043e\u043d\u044f\u043b \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0410\u043d\u0441\u0438\u0431\u043b\u0430 \u2014 \u043e\u043d\u0438 \u043b\u0435\u0437\u0443\u0442 \u0432 \u0441\u043b\u043e\u0436\u043d\u043e\u0435, \u043d\u0435 \u043e\u0441\u0432\u043e\u0438\u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e. \u0414\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0432\u0441\u0435\u043b\u0435\u043d\u0441\u043a\u043e\u0439 \u043d\u0435\u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0410\u043d\u0441\u0438\u0431\u043b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87084","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0441\u043d\u043e\u0432\u044b Ansible, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0448\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0438 \u2014 \u043a\u043e\u043c\u043e\u043a \u0441\u043b\u0438\u043f\u0448\u0438\u0445\u0441\u044f \u043c\u0430\u043a\u0430\u0440\u043e\u043d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/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\udd47Bazele Ansible, f\u0103r\u0103 de care playbook-urile tale sunt un ghem de paste lipite | ProHoster","description":"Fac multe recenzii pentru codul altora \u00een Ansible \u0219i scriu mult eu \u00eensumi.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0441\u043d\u043e\u0432\u044b Ansible, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0448\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0438 \u2014 \u043a\u043e\u043c\u043e\u043a \u0441\u043b\u0438\u043f\u0448\u0438\u0445\u0441\u044f \u043c\u0430\u043a\u0430\u0440\u043e\u043d | ProHoster","og:description":"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-03T11:42:34+00:00","article:modified_time":"2020-07-03T11:42:34+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87084","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:58:53","updated":"2026-02-22 15:29:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/87084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=87084"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/87084\/revisions"}],"predecessor-version":[{"id":162161,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/87084\/revisions\/162161"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=87084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=87084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=87084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}