Unë bëj shumë rishikime për kodin e tjerëve në Ansible dhe shkruaj shumë vetë. Gjatë analizës së gabimeve (si të tjerëve ashtu edhe të mia), si dhe një sërë intervistash, kuptova gabimin kryesor që bëjnë përdoruesit e Ansible — ata merren me gjëra komplekse pa zotëruar bazat.
Për të korrigjuar këtë padrejtësi universale, vendosa të shkruaj një hyrje në Ansible për ata që e njohin tashmë. Paralajmëroj, kjo nuk është një përmbledhje e manualeve, është një artikull i gjatë me shumë shkronja dhe pa figura.
Niveli i pritur i lexuesit — tashmë ka shkruar disa mijëra rreshta YAML, ka bërë diçka në prodhim, por "gjithçka është ndonjëherë e çrregullt".
Emrat
Gabimi kryesor i përdoruesve të Ansible është të mos dinë se si quhen gjërat. Nëse nuk e dini emrat, nuk mund të kuptoni atë që është shkruar në dokumentacion. Një shembull i dukshëm: në një intervistë, një person, që duket se kishte thënë se kishte shkruar shumë në Ansible, nuk ishte në gjendje të përgjigjej për pyetjen "nga cilat elemente përbëhet playbook?". Kur i thashë se "pritej përgjigjja se playbook përbëhet nga play", pasoi një koment shkatërrues "ne nuk e përdorim atë". Njerëzit shkruajnë në Ansible për para dhe nuk e përdorin play. Në të vërtetë e përdorin, por nuk e dinë se çfarë është.
Pra, le të fillojmë me të thjeshtën: si quhen gjërat. Ndoshta e dini këtë, ndoshta jo, sepse nuk e keni vënë re kur keni lexuar dokumentacionin.
ansible-playbook ekzekuton playbook. Playbook — është një skedar me zgjatjen yml/yaml, brenda të cilit ka diçka të tillë:
---
- hosts: group1
roles:
- role1
- hosts: group2,group3
tasks:
- debug:Ne tashmë e kuptuam se i gjithë ky skedar është playbook. Mund të tregojmë ku janë rolet (roles), ku janë detyrat (tasks). Por ku është play? Dhe çfarë e ndan play nga role ose playbook?
Të gjitha këto janë në dokumentacion. Por kështu i kalojnë. Fillestarët — sepse ka shumë dhe nuk mund ta mbash mend gjithçka menjëherë. Të përvojshëm — sepse janë "gjëra triviale". Nëse jeni të përvojshëm — rilexoni këto faqe të paktën një herë në gjashtë muaj, dhe kodi juaj do të bëhet një klasë më i mirë.
Pra, mbani mend: Playbook — është një listë, përbërë nga play dhe import_playbook.
Kjo është një play:
- hosts: group1
roles:
- role1dhe kjo është gjithashtu një play tjetër:
- hosts: group2,group3
tasks:
- debug:Çfarë është play? Pse është ajo?
Play — është elementi kyç për playbook, sepse play dhe vetëm play lidh listën e roleve dhe/apo detyrave me listën e hosteve ku duhet të ekzekutohen ato. Në thellësitë e dokumentacionit mund të gjejmë përmendje për delegate_to, pluginet e lookup lokale, konfigurimet specifike për network-cli, hostet jump etj. Ato lejojnë të ndryshoni pak vendndodhjen e ekzekutimit të detyrave. Por, harrojeni këtë. Çdo nga këto opsione të mençura ka përdorime të veçanta, dhe ato nuk janë universale. Ne po flasim për gjërat bazike që duhet të dinë dhe përdorin të gjithë.
Nëse dëshironi të ekzekutoni "diçka" "diku" — shkruani play. Jo rol. Jo rol me module dhe delegatë. Thjesht merrni dhe shkruani play. Ku në fushën hosts renditni ku të ekzekutoni, dhe në roles/tasks çfarë të ekzekutoni.
Është e thjeshtë, apo jo? Si mund të jetë ndryshe?
Një nga momentet karakteristike, kur njerëzit ndjejnë dëshirën për ta bërë këtë jo përmes play, është "rol, i cili e konfiguron gjithçka". Dëshirojnë të kenë një rol që konfiguroni dhe serverë çdo lloj të parë, dhe serverë të llojit të dytë.
Një shembull arketipik është monitorimi. Dëshirojnë të kenë një rol monitorimi, i cili do të konfigurojë monitorimin. Roli i monitorimit caktohet në hostet e monitorimit (në përputhje me play-in). Por, rezulton se për monitorimin na duhen të instalojmë paketat në hostet që po monitorojmë. Pse të mos përdorim delegate? Dhe gjithashtu duhet të konfigurojmë iptables. delegate? Dhe gjithashtu duhet të shkruajmë/rregullojmë konfigurimin për DBMS-në, që monitorimi të funksionojë. delegate! E nëse krijimtaria është nën flakë, mund të bëjmë delegimin include_role në një cikël të thelluar përmes një filtri të zgjuar mbi listën e grupeve, dhe brenda include_role mund të bëni gjithashtu delegate_to sërish. Dhe fillon kështu…
Një dëshirë e mirë — të kesh një rol të vetme monitorimi, i cili "bën gjithçka" — na çon në një kaos të tmerrshëm nga i cili shpesh ka një dalje: ta shkruajmë gjithçka nga fillimi.
Ku ndodhi gabimi këtu? Në momentin kur zgjodhët se për të ekzekutuar detyrën "x" në hostin X duhet të shkoni në hostin Y dhe të bëni aty "y", duhej të ishit angazhuar në një ushtrim të thjeshtë: të shkoni dhe të shkruani play, e cila në hostin Y bën y. Të mos shtoni diçka në "x", por ta shkruani nga fillimi. Edhe pse me variabla të koduar ngurtë.
Duket se, në paragrafët më sipër gjithçka është thënë saktë. Por kjo nuk është rasti juaj! Sepse dëshironi të shkruani kod të ri përdorues që është DRY dhe ngjan si një bibliotekë, dhe duhet të kërkoni një metodë për ta bërë këtë.
Këtu fshihet një tjetër gabim i rëndë. Një gabim, i cili shndërroi shumë projekte nga ato që ishin shkruar në mënyrë të pranueshme (mund të ishte më mirë, por gjithçka funksionon dhe është e lehtë për të shtuar) në një tmerr të plotë, në të cilin edhe autori nuk mund të kuptojë. Ai funksionon, por mbrohu Zot që të ndryshosh diçka.
Ky gabim tingëllon kështu: roli është një funksion bibliotekar. Kjo analogji ka shkatërruar kaq shumë fillesa të mira, saqë është thjesht e trishtueshme të shikosh. Roli nuk është një funksion bibliotekar. Ai nuk mund të bëjë llogaritje dhe nuk mund të marrë vendime në nivelin e play. Më kujto, cilat janë vendimet që merr play?
Faleminderit, keni të drejtë. Play merr një vendim (në fakt, përmban informacion) se cilat detyra dhe role duhet të ekzekutohet në cilat hoste.
Nëse ju delegoni këtë vendim te roli, madje edhe me llogaritje, e dënon veten tuaj (dhe atë që do të përpiqet të kuptojë kodin tuaj) në një ekzistencë të mjerueshme. Roli nuk vendos se ku do të ekzekutohet. Ky vendim merret nga play. Roli bën atë që i është thënë, atje ku i është thënë.
Pse është e rrezikshme të merresh me programimin në Ansible dhe pse COBOL është më mirë se Ansible do të flasim në kapitullin për variablat dhe jinja. Për momentin le të themi një gjë — çdo llogaritje që bëni lë pas një shenjë të padiskutueshme nga ndryshimi i variablave globale, dhe nuk mund të bëni asgjë për këtë. Sapo dy "shenja" të kryqëzohen — gjithçka është humbur.
Vërejtje për ata që janë të vëmendshëm: roli, sigurisht, mund të ndikojë në rrjedhën e kontrollit. Ka delegate_to dhe ai ka përdorime të arsyeshme. Ka meta: end host/play. Por! Mos harroni, ne po mësojmë bazat? E harruat për delegate_to. Po flasim për kodin më të thjeshtë dhe më të bukur në Ansible. I cili është i lehtë për tu lexuar, i lehtë për tu shkruar, i lehtë për tu debuguar, i lehtë për tu testuar dhe i lehtë për tu shtuar. Kështu që, edhe një herë:
play dhe vetëm play vendos se në cilat hoste ekzekutohet çfarë.
Në këtë seksion ne kuptuam kundërshtimin midis play dhe rolit. Tani do të flasim për marrëdhëniet tasks vs role.
Detyrat dhe Roli
Le të shqyrtojmë play:
- hosts: somegroup
pre_tasks:
- some_tasks1:
roles:
- role1
- role2
post_tasks:
- some_task2:
- some_task3:Le të supozojmë se duhet të bëni foo. Dhe duket kështu foo: name=foobar state=present. Ku duhet ta shkruani këtë? në pre? post? Të krijoni rol?
… Dhe ku shkuan detyrat?
Ne përsëri fillojmë nga bazat — struktura e play. Nëse jeni të humbur në këtë çështje, nuk mund ta përdorni play si bazë për gjithçka tjetër, dhe rezultati juaj do të jetë "i paqëndrueshëm".
Dispositivi play: direktiva hosts, konfigurimet e play vetë dhe seksionet pre_tasks, tasks, roles, post_tasks. Parametrat e tjerë për play nuk janë të rëndësishme për ne tani.
Rendi i seksioneve të tyre me detyra dhe role: pre_tasks, roles, tasks, post_tasks. Duke qenë se rendi semantik i ekzekutimit midis tasks dhe roles nuk është i qartë, best practices thotë se ne shtojmë seksionin tasks, vetëm nëse nuk ka roles. Nëse ka roles, atëherë të gjitha detyrat e bashkëngjitura vendosen në seksionet pre_tasks/post_tasks.
Ka mbetur vetëm ajo që është semantikisht e qartë: së pari pre_tasks, pastaj roles, pastaj post_tasks.
Por ne ende nuk kemi përgjigjur në pyetjen: ku duhet të shkruajmë thirrjen e modulit foo ? A duhet të shkruajmë një rol të tërë për çdo modul? Apo është më mirë të kemi një rol të gjerë për gjithçka? Dhe nëse nuk është rol, ku të shkruajmë – në pre ose në post?
Nëse për këto pyetje nuk ka një përgjigje të arsyeshme, atëherë kjo është një shenjë e mungesës së intuitës, pra ato "theme të drunjta". Le të analizojmë. Së pari, një pyetje kontrolli: Nëse play ka pre_tasks dhe post_tasks dhe nuk ka as detyra, as role, a mund të prishet diçka nëse e zhvendos detyrën e parë nga post_tasks në fund pre_tasks?
?
Sigurisht, formulimi i pyetjes sugjeron se diçka do të prishet. Por çfarë konkretnisht? pre_tasks… Handlerët. Leximi i bazave hap një fakt të rëndësishëm: të gjithë handlerët flush’ohen automatikisht pas çdo seksioni. Pra, ekzekutohen të gjitha detyrat nga post_tasks , pastaj të gjithë handlerët që ishin notify. Pastaj ekzekutohen të gjitha rolet dhe të gjithë handlerët që ishin notify në role. Pastaj
dhe handlerët e tyre. post_tasks në pre_tasksPrandaj, nëse ju e zhvendosni një detyrë nga pre_tasks , potencialisht, do ta ekzekutoni atë para se të kryehet handler’i. Për shembull, nëse në serverin web, ndërsa në post_tasks instalohet dhe konfigurohet pre_tasks diçka i dërgohet, atëherë zhvendosja e kësaj detyre në seksionin
do të çojë në atë që në momentin e "dërgimit" serveri ende nuk do të jetë ndjekur dhe gjithçka do të prishet. pre_tasks dhe post_tasks? Например, для того, чтобы выполнить всё нужное (включая хэндлеры) до выполнения роли. А post_tasks do të na lejojë të punojmë me rezultatet e ekzekutimit të roleve (duke përfshirë handlerët).
Një njohës i hollësishëm i Ansible do të na thotë se ka meta: flush_handlers, por përse na nevojitet flush_handlers, nëse mund të mbështetemi te rendi i ekzekutimit të seksioneve në play? Më shumë se kaq, përdorimi i meta: flush_handlers mund të na sjellë befasi me handlerët që përsëriten, të na bëjë të kemi paralajmërime të çuditshme në rastin e përdorimit të when i block etj. Sa më shumë të njohni ansiblin, aq më shumë nuanca do të jeni në gjendje të përmendni për "zgjidhjen e zgjuar". Dhe zgjidhja e thjeshtë — përdorimi i ndarjes natyrore midis pre/roles/post — nuk shkakton nuanca.
Dhe, po kthehemi te ‘foo’ ynë. Ku ta vendosim atë? Në pre, post apo në roles? Është e qartë, kjo varet nëse na duhen rezultatet e punës së handler-it për foo. Nëse jo, atëherë foo nuk ka nevojë të vendoset as në pre, as në post — këto seksione kanë një kuptim të veçantë — ekzekutimi i detyrave para dhe pas arrays kryesor të kodit.
Tani, përgjigjja në pyetjen "rol apo detyrë" përfundon të jetë ajo që tashmë ekziston në play — nëse atje ka tasks, atëherë duhet të shtohet në tasks. Nëse ka roles — duhet të bëjmë rol (qoftë edhe prej një detyre). Ju rikujtoj, tasks dhe roles nuk përdoren njëkohësisht.
Kuptimi i bazave të Ansible ofron përgjigje të arsyeshme për, dukshëm, pyetje me shije.
Detyrat dhe rolet (pjesa e dytë)
Tani, le të diskutojmë situatën kur vetëm filloni të shkruani një playbook. Ju nevojitet të bëni foo, bar dhe baz. A janë këto tri detyra, një rol apo tri role? Për të përmbledhur pyetjen: në çfarë momenti duhet të filloni të shkruani role? Çfarë ka kuptim të shkruani role, kur mund të shkruani detyra?… Çfarë është një rol?
Një nga gabimet më të mëdha (këtë kam përmendur tashmë) është të mendosh se roli është si një funksion në bibliotekën e një programi. Si duket përshkrimi i përgjithshëm i një funksioni? Ai merr argumente si input, ndërvepron me side causes, bën side effects, kthen një vlerë.
Tani, vëmendje. Çfarë prej kësaj mund të bëhet në rol? Të thërrasësh side effects — gjithmonë me kënaqësi, kjo është themeli i gjithçkaje Ansible — të bësh side effects. Të kesh side causes? Elementar. Por me "të kaluar një vlerë dhe ta kthejmë atë" — këtu është problemi. Së pari, nuk mund të kalosh një vlerë në rol. Mund të vendosësh një variabël globale me jetëgjatësi sa play në seksionin vars për rolin. Mund të vendosësh një variabël globale me jetëgjatësi në play brenda rolit. Apo madje edhe me jetëgjatësi playbook-esh (set_fact/register). Por nuk mund të kesh "variabla lokale". Nuk mund të "pranosh një vlerë" dhe "ta kthesh atë".
Nga kjo përfundon se: nuk mund të shkruash diçka në ansible dhe të mos e thërrasësh side effects. Ndryshimi i variablave globale është gjithmonë një side effect për funksionin. Në Rust, për shembull, ndryshimi i një varianti global është unsafe. Ndërsa në Ansible — metoda e vetme për të ndikuar në vlerat për rol. Vini re fjalët e përdorura: jo "të kalosh një vlerë në rol", por "të ndryshosh vlerat që përdor roli". Ndër rollet nuk ka izolim. Ndër detyrat dhe rolet nuk ka izolim.
Pra, në përfundim: roli është jo një funksion.
Çfarë është e mirë në rolin? Së pari, roli ka vlera të paracaktuara (/default/main.yaml), së dyti, roli ka katalogë shtesë për ruajtjen e skedave.
Çfarë është e mirë në vlerat e paracaktuara? Ato janë, që në piramidën e Maslow-it, një tabelë shumë të çuditshme të prioriteteve të variablave në Ansible, defaultet e rolit janë më pak të prioritizuara (përveç parametrave të linjës së komandës së Ansible). Kjo do të thotë se, nëse duhet t'i ofroni vlera të paracaktuara dhe të mos shqetësoheni se ato do të zëvendësojnë vlerat nga inventari ose variablat grupor, atëherë defaultet e rolit janë vendi i vetëm i duhur për ju. (Po, pak po gënjej — ka edhe |d(your_default_here), por nëse flasim për vendet statike — atëherë vetëm defaultet e rolit).
Çfarë tjetër është e mirë në role? Ato kanë katalogët e tyre. Këto janë katalogë për variablat, si konstantë (pra, të llogaritur për rolin), ashtu dhe për dinamikë (ka një model ose anti-model të tillë — include_vars më bashkë me {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Këto janë katalogë për files/, templates/. Gjithashtu, ato lejojnë që rolet të kenë modulat dhe plug-in-at e tyre (library/). Por, në krahasim me detyrat në playbook (e cila gjithashtu mund të ketë të gjitha këto), përfitimi këtu është vetëm se skedarët nuk janë hedhur në një grumbull të vetëm, por në disa grumbuj të ndarë.
Një detaj tjetër: mund të përpiqeni të bëni role që do të jenë të disponueshme për ripërdorim (përmes galaxy). Pas shfaqjes së koleksioneve, shpërndarja e rolëve mund të konsiderohet pothuajse e harxhuar.
Kështu, rolet kanë dy veçori të rëndësishme: ato kanë defaultet (një veçori unike) dhe lejojnë strukturimin e kodit.
Duke u kthyer në pyetjen fillestare: kur të krijohen detyrat dhe kur rolet? Detyrat në playbook shpesh përdoren ose si "lidhëse" para/pas rolëve, ose si një element ndihmës të ndërtimit (atëherë në kod nuk duhet të ketë role). Një grumbull detyrash normale në përzierje me rolet — është padyshim një pamje e papastër. Duhet të ndiqet një stil të caktuar — ose detyra, ose role. Role ofrojnë ndarje entitetesh dhe defaultet, detyrat lejojnë që kodi të lexohet më shpejt. Zakonisht në rol dërgohen kodet më "statike" (të rëndësishme dhe të ndërlikuara), ndërsa në stilin e detyrave shkruhen skriptet mbështetëse.
Ka ekziston mundësia për të bërë import_role si detyrë, por nëse e shkruani këtë, bëhuni gati për një shpjegim për ndjenjën tuaj estetike, pse dëshironi ta bëni këtë.
Një lexues i bezdisshëm mund të thotë se rolet mund të importojnë role, dhe rolet mund të kenë varësi përmes galaxy.yml, dhe ka gjithashtu diçka të frikshme dhe të tmerrshme include_role — ju kujtoj, ne po përmirësojmë aftësitë në Ansible-n themelor, e jo në gimnasitikën ritmike.
Handlerat dhe detyrat
Le të diskutojmë për një tjetër gjë të dukshme: handlerat. Aftësia për t'i përdorur ato siç duhet është thuajse një art. Cila është diferenca midis një handleri dhe një detyrë?
Ata që po e kujtojmë themelin, ja një shembull:
- hosts: group1
tasks:
- foo:
notify: handler1
handlers:
- name: handler1
bar:Në rolin e handlerave, ato ndodhen në rolename/handlers/main.yaml. Handlerat ndahen midis të gjithë pjesëmarrësve në play: pre/post_tasks mund të thërrasin handlerat e rolit, dhe roli mund të thërrasë handlerat nga play. Megjithatë, thirrjet "cross-role" të handlerave shkaktojnë më shumë 'wtf' se sa përsëritja e një handler-i triviale. (Një tjetër element i praktikave më të mira — përpiquni të mos bëni përsëritje të emrave të handlerave).
Dallimi kryesor është se një detyrë ekzekutohet (ideompatentisht) gjithmonë (plus/minus etiketat dhe when), kurse handleri ekzekutohet sipas ndryshimit të gjendjes (notify vepron vetëm nëse ka pasur ndryshim). Çfarë do t'i sjellë kjo? P.sh., se në një ekzekutim të ri, nëse nuk ka qenë ndryshimi, atëherë nuk do të ndodhi as handleri. Dhe pse mund të ndodhë që na nevojitet të ekzekutojmë handlerin kur s’ka pasur një ndryshim në detyrën ndihmuese? P.sh., sepse diçka ka marrë fund tëjk dhe ka pasur ndryshim, por ekzekutimi nuk arriti në handler. P.sh., sepse rrjeti ishte temporalisht i ndërprerë. Konfigurimi u ndryshua, shërbimi nuk u rilansua. Në ekzekutimin e ardhshëm, konfigurimi tashmë nuk ndryshon, dhe shërbimi mbetet me versionin e vjetër të konfigurimit.
Situata me konfigurimin nuk është e zgjidhshme (në fakt, mund të shpikim një protokoll të veçantë për rilansim me flamuj të skedarëve etj., por kjo nuk është më 'ansible' themelor në asnjë formë). Por ka një tjetër histori të shpeshtë: ne instaluam një aplikacion, shënuam atë .service-skedën, dhe tani duam ta daemon_reload dhe state=started. Dhe vendi natyror për këtë duket si handler. Por nëse e bëni atë një detyrë në fund të listës së detyrave apo një rol, atëherë ai do të ekzekutohet idempotentisht çdo herë. Edhe nëse playbook-u dështon në mes. Kjo nuk zgjidh problemin e restarted (nuk mund të bëni një detyrë me atributin restarted, pasi do të humbasë idempotentësinë), por me siguri duhet të bëni state=started, stabiliteti i përgjithshëm i playbook-ëve rritet, pasi zvogëlohet numri i lidhjeve dhe gjendjes dinamike.
Një pronë tjetër pozitive e handler-it është se nuk ndot daljen. Nëse nuk kishte ndryshime — nuk ka skipped të tepërta ose ok në dalje — është më e lehtë për tu lexuar. Kjo është gjithashtu një pronë negative — nëse gjen një gabim në një task të ekzekutuar linear në përpjekjen e parë, handler-at do të ekzekutohen vetëm kur ka ndryshime, domethënë në disa kushte — shumë rrallë. Për shembull, për herë të parë në jetë pas pesë vjetësh. Dhe, natyrisht, do të ketë një gabim në emër dhe gjithçka do të bjerë. Dhe herën tjetër nuk mund të nisen — nuk ka ndryshime.
Përveç kësaj, duhet të flasim për arritshmërinë e variablave. Për shembull, nëse bëni notify për një detyrë me cikël, çfarë do të ketë në variabla? Mund të arrini të kuptoni në mënyrë analitike, por nuk është gjithmonë triviale, sidomos nëse variablat vijnë nga vende të ndryshme.
… Pra, handler-at janë shumë më pak të dobishëm dhe shumë më të problematikë se sa duken. Nëse mund të shkruani diçka bukur (pa komplimente) pa handler-a, është më mirë ta bëni pa to. Nëse nuk del bukur — është më mirë me to.
Lexuesi i këndshëm e vëren drejt se nuk e kemi diskutuar listen, se handler-i mund të thërrasë notify për një handler tjetër, se handler-i mund të përfshijë import_tasks (i cili mund të bëjë include_role me with_items), se sistemi i handler-ëve në Ansible është Turing-complete, se handlerët nga include_role mund të ndërthuren mrekullisht me handlerët nga play dhe kështu me radhë — gjithçka kjo nuk është qartë "bazike").
Megjithatë, ka një çështje të caktuar WTF, që në fakt është një veçori, dhe që duhet mbajtur mend. Nëse keni një detyrë që ekzekutohet me delegate_to dhe ka notify, atëherë handler-i përkatës ekzekutohet pa delegate_to, domethënë në hostin ku është caktuar play. (Megjithëse handler-i, natyrisht, mund të ketë delegate_to po ashtu).
Veçanërisht, dua të them disa fjalë për rolet e ripërdorshme. Para se të shfaqeshin koleksionet, kishte idenë se mund të bëhen role universale që mund të ansible-galaxy install Dhe shkoi. Funksionon në të gjitha OS-të për të gjitha rastet në çdo situatë. Kështu, mendimi im është: kjo nuk funksionon. Çdo rol me mbështetje për 100500 raste është e dënuar të përballet me thellësitë e problemeve të skenarëve të raritetit. Ato mund të mbyllen me testime masive, por si me çdo testim, ose keni një produkt të dekartuar të vlerave hyrëse dhe një funksion total, ose keni "mbuluar skenare të veçantë". Mendimi im është se është shumë më mirë nëse roli është linear (kompleksiteti ciklomatk 1). include_varsSa më pak if'esh (të dukshme ose deklarative - në formë
ose formë when për grupin e variablave), aq më mirë është roli. Ndonjëherë duhet të bëni ndarjen, por, do ta përsëris, sa më pak të jenë, aq më mirë. Pra, duket se një rol i mirë me galaxy (funksionon!) me shumë include_vars mund të jetë më pak i preferuar se "rolin tuaj" me pesë detyra. Momenti kur roli me galaxy është më mirë - kur filloni të shkruani diçka. Momenti kur bëhet më keq - kur diçka prishet, dhe keni dyshimin se është për shkak të "rolit me galaxy". E hapni, dhe atje janë pesë përfshirje, tetë lista detyrash dhe një grumbull when ‘ash… Dhe duhet të merremi me këtë. Në vend të 5 detyrave në një listë lineare, ku nuk ka asgjë për t'u prishur. whenNë pjesët e ardhshme
Pak për inventarin, variablat grupore, plugin-in host_group_vars, hostvars. Si të lidhni spaghetti në një nyje Gordiane. Shkala dhe prioriteti i variablave, modeli i memories Ansible. "Atëherë ku duhet të ruhet emri i përdoruesit për bazën e të dhënave?".
- jinja: {{ jinja }}
— nosql notype nosense plastelinë të butë. Është kudo, madje aty ku nuk e prisni. Pak për!!unsafedhe yaml të shijshëm.Unë bëj shumë rishikime për kodin e të tjerëve në Ansible dhe shkruaj shumë vetë.
Burimi: habr.com
