Bazat e thjeshta, pa të cilat librat e lojërave tuaja do të jenë një grumbull makaronash ngjitëse

Unë bëj shumë rishikime të kodit Ansible të njerëzve të tjerë dhe shkruaj shumë vetë. Gjatë analizës së gabimeve (si të njerëzve të tjerë ashtu edhe të miat), si dhe një sërë intervistash, kuptova gabimin kryesor që bëjnë përdoruesit e Ansible - ata futen në gjëra komplekse pa zotëruar ato themelore.

Për të korrigjuar këtë padrejtësi universale, vendosa të shkruaj një hyrje në Ansible për ata që tashmë e dinë atë. Ju paralajmëroj, kjo nuk është një ritregim i njerëzve, kjo është një histori e vjetër me shumë letra dhe pa foto.

Niveli i pritur i lexuesit është që disa mijëra rreshta yamla janë shkruar tashmë, diçka tashmë është në prodhim, por "disi gjithçka është e shtrembër".

emrat

Gabimi kryesor që bën një përdorues i Ansible është që nuk e di se si quhet diçka. Nëse nuk i dini emrat, nuk mund të kuptoni se çfarë thotë dokumentacioni. Një shembull i gjallë: gjatë një interviste, një person që dukej se thoshte se kishte shkruar shumë në Ansible nuk mund t'i përgjigjej pyetjes "nga çfarë elementesh përbëhet një libër lojërash?" Dhe kur sugjerova se "përgjigjja pritej që libri i lojërave përbëhet nga loja", pasoi komenti mallkim "ne nuk e përdorim atë". Njerëzit shkruajnë Ansible për para dhe nuk përdorin lojën. Ata në fakt e përdorin atë, por nuk e dinë se çfarë është.

Pra, le të fillojmë me diçka të thjeshtë: si quhet? Ndoshta ju e dini këtë, ose ndoshta nuk e dini, sepse nuk i keni kushtuar vëmendje kur keni lexuar dokumentacionin.

ansible-playbook ekzekuton librin e lojërave. Një libër lojërash është një skedar me zgjerimin yml/yaml, brenda të cilit ka diçka si kjo:

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

Ne e kuptuam tashmë se i gjithë ky skedar është një libër lojërash. Mund të tregojmë se ku janë rolet dhe ku janë detyrat. Por ku është loja? Dhe cili është ndryshimi midis lojës dhe rolit ose librit të lojës?

Gjithçka është në dokumentacion. Dhe atyre u mungon. Fillestarët - sepse ka shumë dhe nuk do të mbani mend gjithçka menjëherë. Me përvojë - sepse "gjëra të parëndësishme". Nëse jeni me përvojë, rilexoni këto faqe të paktën një herë në gjashtë muaj dhe kodi juaj do të bëhet kryesues në klasë.

Pra, mbani mend: Playbook është një listë e përbërë nga lojëra dhe import_playbook.
Kjo është një lojë:

- hosts: group1
  roles:
    - role1

dhe kjo është gjithashtu një shfaqje tjetër:

- hosts: group2,group3
  tasks:
    - debug:

Çfarë është loja? Pse është ajo?

Luajtja është një element kyç për një libër lojërash, sepse loja dhe vetëm luajtja lidh një listë rolesh dhe/ose detyrash me një listë të hosteve në të cilat ato duhet të ekzekutohen. Në thellësi të dokumentacionit mund të gjeni përmendje delegate_to, shtojcat e kërkimit lokal, cilësimet specifike të rrjetit, hostet e kërcimit, etj. Ato ju lejojnë të ndryshoni pak vendin ku kryhen detyrat. Por, harrojeni. Secila prej këtyre opsioneve të zgjuara ka përdorime shumë specifike dhe ato definitivisht nuk janë universale. Dhe ne po flasim për gjëra themelore që të gjithë duhet t'i dinë dhe t'i përdorin.

Nëse doni të performoni "diçka" "diku", ju shkruani lojë. Jo një rol. Jo një rol me module dhe delegatë. Ju merrni atë dhe shkruani lojë. Në të cilën, në fushën e hosteve ju listoni se ku të ekzekutoni, dhe në role/detyra - çfarë të ekzekutoni.

E thjeshtë, apo jo? Si mund të ishte ndryshe?

Një nga momentet karakteristike kur njerëzit kanë dëshirë ta bëjnë këtë jo përmes lojës është "roli që vendos gjithçka". Do të doja të kisha një rol që konfiguron të dy serverët e tipit të parë dhe serverët e tipit të dytë.

Një shembull arketip është monitorimi. Do të doja të kisha një rol monitorues që do të konfiguronte monitorimin. Roli i monitorimit u është caktuar pritësve monitorues (sipas lojës). Por rezulton se për monitorim duhet të dërgojmë paketa tek hostet që po monitorojmë. Pse të mos përdorni delegatin? Ju gjithashtu duhet të konfiguroni iptables. delegat? Ju gjithashtu duhet të shkruani/korrigjoni një konfigurim për DBMS për të mundësuar monitorimin. delego! Dhe nëse mungon kreativiteti, atëherë mund të bëni një delegacion include_role në një lak të mbivendosur duke përdorur një filtër të ndërlikuar në një listë grupesh dhe brenda include_role ju mund të bëni më shumë delegate_to përsëri. Dhe largohemi...

Një dëshirë e mirë - të kemi një rol të vetëm monitorues, i cili "bën gjithçka" - na çon në ferr të plotë nga i cili më shpesh ka vetëm një rrugëdalje: të rishkruajmë gjithçka nga e para.

Ku ndodhi gabimi këtu? Në momentin që zbulove se për të bërë detyrën "x" në hostin X, duhet të shkosh te hosti Y dhe të bësh "y" atje, duhet të bësh një ushtrim të thjeshtë: të shkosh dhe të shkruash play, që në host Y bën y. Mos shtoni diçka në "x", por shkruani atë nga e para. Edhe me variabla të koduar.

Duket se gjithçka në paragrafët e mësipërm është thënë saktë. Por ky nuk është rasti juaj! Sepse dëshironi të shkruani kod të ripërdorshëm që është DRY dhe i ngjashëm me bibliotekën, dhe ju duhet të kërkoni një metodë se si ta bëni atë.

Këtu fshihet një gabim tjetër i rëndë. Një gabim që ktheu shumë projekte nga të shkruara me tolerancë (mund të ishte më mirë, por gjithçka funksionon dhe është e lehtë për t'u përfunduar) në një tmerr të plotë që as autori nuk mund ta kuptojë. Funksionon, por Zoti ju ruajt të ndryshoni ndonjë gjë.

Gabimi është: roli është një funksion i bibliotekës. Kjo analogji ka shkatërruar aq shumë fillime të mira sa është thjesht e trishtueshme të shikosh. Roli nuk është funksion i bibliotekës. Ajo nuk mund të bëjë llogaritë dhe nuk mund të marrë vendime në nivelin e lojës. Më kujto çfarë vendimesh merr loja?

Faleminderit, keni të drejtë. Play merr një vendim (më saktë, përmban informacion) se cilat detyra dhe role duhet të kryejnë në cilin host.

Nëse ia delegoni këtë vendim një roli, madje edhe me kalkulime, ju e dënoni veten (dhe atë që do të përpiqet të analizojë kodin tuaj) në një ekzistencë të mjerueshme. Roli nuk vendos se ku kryhet. Ky vendim merret me lojë. Roli bën atë që i thuhet, aty ku i thuhet.

Pse është i rrezikshëm programimi në Ansible dhe pse COBOL është më i mirë se Ansible do të flasim në kapitullin për variablat dhe xhinxha. Tani për tani, le të themi një gjë - secila nga llogaritjet tuaja lë pas një gjurmë të pashlyeshme të ndryshimeve në variablat globale, dhe ju nuk mund të bëni asgjë për këtë. Sapo u kryqëzuan dy “gjurmët”, gjithçka ishte zhdukur.

Shënim për të këputurit: roli me siguri mund të ndikojë në rrjedhën e kontrollit. Hani delegate_to dhe ka përdorime të arsyeshme. Hani meta: end host/play. Por! Mos harroni se ne mësojmë bazat? Harruar për delegate_to. Po flasim për kodin më të thjeshtë dhe më të bukur Ansible. E cila është e lehtë për t'u lexuar, e lehtë për t'u shkruar, e lehtë për t'u korrigjuar, e lehtë për t'u testuar dhe e lehtë për t'u plotësuar. Pra, edhe një herë:

luaj dhe vetëm luajtja vendos se cilat hoste do të ekzekutohen.

Në këtë pjesë trajtuam kundërshtimin midis lojës dhe rolit. Tani le të flasim për marrëdhëniet e detyrave dhe rolit.

Detyrat dhe rolet

Merrni parasysh të luani:

- hosts: somegroup
  pre_tasks:
    - some_tasks1:
  roles:
     - role1
     - role2
  post_tasks:
     - some_task2:
     - some_task3:

Le të themi se ju duhet të bëni një gjë të tillë. Dhe duket si foo: name=foobar state=present. Ku duhet ta shkruaj këtë? në para? postim? Krijo një rol?

...Dhe ku shkuan detyrat?

Ne po fillojmë përsëri me bazat - pajisjen e luajtjes. Nëse qëndroni në këtë çështje, nuk mund ta përdorni lojën si bazë për gjithçka tjetër dhe rezultati juaj do të jetë "i lëkundur".

Pajisja e luajtjes: direktiva e hosteve, cilësimet për vetë lojën dhe detyrat para, detyrat, rolet, seksionet e post_detyrave. Parametrat e mbetur për lojë nuk janë të rëndësishme për ne tani.

Renditja e seksioneve të tyre me detyra dhe role: pre_tasks, roles, tasks, post_tasks. Meqënëse semantikisht rendi i ekzekutimit është ndërmjet tasks и roles nuk është e qartë, atëherë praktikat më të mira thonë se po shtojmë një seksion tasks, vetëm nëse jo roles... Nëse ka roles, pastaj të gjitha detyrat e bashkangjitura vendosen në seksione pre_tasks/post_tasks.

Mbetet vetëm se gjithçka është e qartë semantikisht: së pari pre_tasks, atëherë roles, atëherë post_tasks.

Por ne ende nuk i jemi përgjigjur pyetjes: ku është thirrja e modulit? foo shkruaj? A duhet të shkruajmë një rol të tërë për çdo modul? Apo është më mirë të kesh një rol të trashë për gjithçka? Dhe nëse jo një rol, atëherë ku duhet të shkruaj - para apo postim?

Nëse nuk ka përgjigje të arsyetuar për këto pyetje, atëherë kjo është një shenjë e mungesës së intuitës, domethënë të njëjtave "themelet e lëkundshme". Le ta kuptojmë. Së pari, një pyetje sigurie: Nëse loja ka pre_tasks и post_tasks (dhe nuk ka detyra apo role), atëherë a mund të prishet diçka nëse kryej detyrën e parë nga post_tasks Do ta çoj deri në fund pre_tasks?

Natyrisht, formulimi i pyetjes lë të kuptohet se do të prishet. Por çfarë saktësisht?

... Trajtuesit. Leximi i bazave zbulon një fakt të rëndësishëm: të gjithë mbajtësit pastrohen automatikisht pas çdo seksioni. Ato. të gjitha detyrat nga pre_tasks, pastaj të gjithë mbajtësit që u njoftuan. Pastaj të gjitha rolet dhe të gjithë mbajtësit që janë njoftuar në role janë ekzekutuar. Pas post_tasks dhe mbajtësit e tyre.

Kështu, nëse tërhiqni një detyrë nga post_tasks в pre_tasks, atëherë potencialisht do ta ekzekutoni përpara se të ekzekutohet mbajtësi. për shembull, nëse në pre_tasks serveri i uebit është instaluar dhe konfiguruar, dhe post_tasks diçka i dërgohet, pastaj transferojeni këtë detyrë në seksion pre_tasks do të çojë në faktin se në kohën e "dërgimit" serveri nuk do të funksionojë ende dhe gjithçka do të prishet.

Tani le të mendojmë përsëri, pse kemi nevojë pre_tasks и post_tasks? Për shembull, për të përfunduar gjithçka të nevojshme (përfshirë mbajtësit) përpara se të përmbushni rolin. A post_tasks do të na lejojë të punojmë me rezultatet e ekzekutimit të roleve (përfshirë mbajtësit).

Një ekspert i zgjuar Ansible do të na tregojë se çfarë është. meta: flush_handlers, por pse na duhen flush_handlers nëse mund të mbështetemi në rendin e ekzekutimit të seksioneve në lojë? Për më tepër, përdorimi i meta: flush_handlers mund të na japë gjëra të papritura me mbajtës të dyfishtë, duke na dhënë paralajmërime të çuditshme kur përdoren when у block etj. Sa më mirë të njihni ansiblen, aq më shumë nuanca mund të emërtoni për një zgjidhje "të ndërlikuar". Dhe një zgjidhje e thjeshtë - duke përdorur një ndarje të natyrshme midis para / roleve / post - nuk shkakton nuanca.

Dhe, përsëri te 'foo'-ja jonë. Ku duhet ta vendos? Në para, post apo role? Natyrisht, kjo varet nga fakti nëse na duhen rezultatet e mbajtësit për foo. Nëse nuk janë aty, atëherë foo nuk ka nevojë të vendoset as në para as në post - këto seksione kanë një kuptim të veçantë - ekzekutimi i detyrave para dhe pas trupit kryesor të kodit.

Tani përgjigjja e pyetjes "roli ose detyra" zbret në atë që tashmë është në lojë - nëse ka detyra atje, atëherë duhet t'i shtoni ato në detyra. Nëse ka role, duhet të krijoni një rol (qoftë nga një detyrë). Më lejoni t'ju kujtoj se detyrat dhe rolet nuk përdoren në të njëjtën kohë.

Kuptimi i bazave të Ansible jep përgjigje të arsyeshme për pyetjet në dukje të shijes.

Detyrat dhe rolet (pjesa e dytë)

Tani le të diskutojmë situatën kur sapo keni filluar të shkruani një libër lojërash. Ju duhet të bëni foo, bar dhe baz. A janë këto tre detyra, një rol apo tre role? Për të përmbledhur pyetjen: në cilën pikë duhet të filloni të shkruani role? Çfarë kuptimi ka të shkruash role kur mund të shkruash detyra?... Çfarë është një rol?

Një nga gabimet më të mëdha (kam folur tashmë për këtë) është të mendosh se një rol është si një funksion në bibliotekën e një programi. Si duket një përshkrim i përgjithshëm i funksionit? Ai pranon argumente hyrëse, ndërvepron me shkaqet anësore, bën efekte anësore dhe kthen një vlerë.

Tani, vëmendje. Çfarë mund të bëhet nga kjo në rol? Jeni gjithmonë të mirëpritur të quani efekte anësore, ky është thelbi i të gjithë Ansible - për të krijuar efekte anësore. A ka shkaqe anësore? Elementare. Por me "kaloni një vlerë dhe kthejeni atë" - këtu nuk funksionon. Së pari, nuk mund t'i kalosh një vlerë një roli. Ju mund të vendosni një variabël globale me një madhësi të lojës gjatë gjithë jetës në seksionin vars për rolin. Ju mund të vendosni një variabël globale me një lojë të përjetshme brenda rolit. Ose edhe me jetëgjatësinë e librave të lojërave (set_fact/register). Por nuk mund të kesh "ndryshore lokale". Ju nuk mund të "merrni një vlerë" dhe "ta ktheni atë".

Gjëja kryesore rrjedh nga kjo: nuk mund të shkruani diçka në Ansible pa shkaktuar efekte anësore. Ndryshimi i variablave globale është gjithmonë një efekt anësor për një funksion. Në Rust, për shembull, ndryshimi i një ndryshoreje globale është unsafe. Dhe në Ansible është e vetmja metodë për të ndikuar në vlerat për një rol. Vini re fjalët e përdorura: jo "kaloni një vlerë në rol", por "ndryshoni vlerat që përdor roli". Nuk ka izolim midis roleve. Nuk ka izolim midis detyrave dhe roleve.

Total: një rol nuk është një funksion.

Çfarë është e mirë për rolin? Së pari, roli ka vlerat e paracaktuara (/default/main.yaml), së dyti, roli ka drejtori shtesë për ruajtjen e skedarëve.

Cilat janë përfitimet e vlerave të paracaktuara? Për shkak se në piramidën e Maslow, tabelën mjaft të shtrembëruar të prioriteteve të ndryshueshme të Ansible, parazgjedhjet e roleve janë me prioritet më të ulët (minus parametrat e linjës së komandës Ansible). Kjo do të thotë që nëse keni nevojë të jepni vlerat e paracaktuara dhe të mos shqetësoheni që ato të tejkalojnë vlerat nga inventari ose variablat e grupit, atëherë parazgjedhja e roleve është vendi i vetëm i duhur për ju. (Po gënjej pak - ka më shumë |d(your_default_here), por nëse flasim për vende të palëvizshme, atëherë vetëm rolet janë parazgjedhur).

Çfarë tjetër është e mrekullueshme për rolet? Sepse ata kanë katalogët e tyre. Këto janë direktori për variabla, si konstante (d.m.th. të llogaritura për rolin) ashtu edhe dinamike (ka ose një model ose një anti-model - include_vars me {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Këto janë drejtoritë për files/, templates/. Gjithashtu, ju lejon të keni modulet dhe shtojcat tuaja (library/). Por, në krahasim me detyrat në një libër lojërash (që gjithashtu mund t'i ketë të gjitha këto), përfitimi i vetëm këtu është se skedarët nuk hidhen në një grumbull, por në disa grumbuj të veçantë.

Një detaj tjetër: mund të provoni të krijoni role që do të jenë të disponueshme për ripërdorim (nëpërmjet galaxy). Me ardhjen e koleksioneve, shpërndarja e roleve mund të konsiderohet pothuajse e harruar.

Kështu, rolet kanë dy veçori të rëndësishme: ato kanë parazgjedhje (një veçori unike) dhe ju lejojnë të strukturoni kodin tuaj.

Duke iu rikthyer pyetjes origjinale: kur të kryeni detyra dhe kur të bëni role? Detyrat në një libër lojërash përdoren më shpesh ose si "ngjitës" para/pas roleve, ose si një element ndërtimi i pavarur (atëherë nuk duhet të ketë role në kod). Një grumbull detyrash normale të përziera me role është paqartësi e paqartë. Ju duhet t'i përmbaheni një stili specifik - një detyrë ose një rol. Rolet ofrojnë ndarje të entiteteve dhe parazgjedhjeve, detyrat ju lejojnë të lexoni kodin më shpejt. Zakonisht, kodet më "stacionare" (të rëndësishme dhe komplekse) vendosen në role dhe skriptet ndihmëse shkruhen në stilin e detyrës.

Është e mundur të bësh import_role si detyrë, por nëse e shkruani këtë, atëherë përgatituni t'i shpjegoni sensit tuaj të bukurisë pse dëshironi ta bëni këtë.

Një lexues i zgjuar mund të thotë se rolet mund të importojnë role, rolet mund të kenë varësi nëpërmjet galaxy.yml, dhe ka gjithashtu një të tmerrshme dhe të tmerrshme include_role — Ju kujtoj se po përmirësojmë aftësitë në Ansible bazë dhe jo në gjimnastikë figurative.

Trajtuesit dhe detyrat

Le të diskutojmë një gjë tjetër të dukshme: mbajtësit. Të dish se si t'i përdorësh ato në mënyrë korrekte është pothuajse një art. Cili është ndryshimi midis një mbajtës dhe një zvarritjeje?

Meqenëse po kujtojmë bazat, këtu është një shembull:

- hosts: group1
  tasks:
    - foo:
      notify: handler1
  handlers:
     - name: handler1
       bar:

Trajtuesit e roleve janë të vendosur në rolename/handlers/main.yaml. Trajtuesit gërmojnë mes të gjithë pjesëmarrësve në lojë: para/post_detyrat mund të tërheqin mbajtësit e roleve dhe një rol mund të tërheqë mbajtësit nga loja. Megjithatë, thirrjet "ndër-role" për mbajtësit shkaktojnë shumë më tepër wtf sesa përsëritja e një mbajtësi të parëndësishëm. (Një element tjetër i praktikave më të mira është të përpiqeni të mos përsërisni emrat e mbajtësve).

Dallimi kryesor është se detyra ekzekutohet gjithmonë (në mënyrë idempotente) (etiketat plus/minus dhe when), dhe mbajtësi - sipas ndryshimit të gjendjes (njofoni zjarret vetëm nëse është ndryshuar). Çfarë do të thotë kjo? Për shembull, fakti që kur rinisni, nëse nuk ka ndryshuar, atëherë nuk do të ketë asnjë mbajtës. Pse mund të na duhet të ekzekutojmë mbajtësin kur nuk ka pasur ndryshim në detyrën gjeneruese? Për shembull, sepse diçka u prish dhe ndryshoi, por ekzekutimi nuk arriti te mbajtësi. Për shembull, sepse rrjeti ishte përkohësisht i fikur. Konfigurimi ka ndryshuar, shërbimi nuk është rifilluar. Herën tjetër që e filloni, konfigurimi nuk ndryshon më dhe shërbimi mbetet me versionin e vjetër të konfigurimit.

Situata me konfigurimin nuk mund të zgjidhet (më saktë, ju mund të shpikni një protokoll të veçantë rinisjeje për veten tuaj me flamuj skedarësh, etj., Por kjo nuk është më "ansible bazë" në asnjë formë). Por ka një histori tjetër të zakonshme: ne instaluam aplikacionin, e regjistruam atë .service-file, dhe tani e duam daemon_reload и state=started. Dhe vendi i natyrshëm për këtë duket të jetë mbajtësi. Por nëse e bëni atë jo një mbajtës, por një detyrë në fund të një liste detyrash ose roli, atëherë ai do të ekzekutohet në mënyrë të pafuqishme çdo herë. Edhe nëse libri i lojërave u prish në mes. Kjo nuk e zgjidh fare problemin e rifilluar (nuk mund të bësh një detyrë me atributin e rifilluar, sepse idempotenca humbet), por padyshim ia vlen të bësh shtet=filluar, stabiliteti i përgjithshëm i librave të lojërave rritet, sepse zvogëlohet numri i lidhjeve dhe gjendja dinamike.

Një veçori tjetër pozitive e mbajtësit është se nuk e bllokon daljen. Nuk kishte ndryshime - nuk ka anashkaluar shtesë ose në rregull në dalje - më e lehtë për t'u lexuar. Është gjithashtu një veti negative - nëse gjeni një gabim shtypi në një detyrë të ekzekutuar në mënyrë lineare në ekzekutimin e parë, atëherë mbajtësit do të ekzekutohen vetëm kur ndryshohen, d.m.th. në disa kushte - shumë rrallë. Për shembull, për herë të parë në jetën time pesë vjet më vonë. Dhe, sigurisht, do të ketë një gabim shtypi në emër dhe gjithçka do të prishet. Dhe nëse nuk i përdorni për herë të dytë, nuk ka asnjë ndryshim.

Më vete, duhet të flasim për disponueshmërinë e variablave. Për shembull, nëse njoftoni një detyrë me një lak, çfarë do të jetë në variablat? Ju mund të merrni me mend në mënyrë analitike, por nuk është gjithmonë e parëndësishme, veçanërisht nëse variablat vijnë nga vende të ndryshme.

... Pra, mbajtësit janë shumë më pak të dobishëm dhe shumë më problematikë sesa duken. Nëse mund të shkruani diçka bukur (pa njolla) pa mbajtës, është më mirë ta bëni pa to. Nëse nuk funksionon bukur, është më mirë me ta.

Me të drejtë lexuesi gërryes vë në dukje se nuk kemi diskutuar listenqë një mbajtës mund të thërrasë notify për një mbajtës tjetër, që një mbajtës mund të përfshijë import_tasks (të cilat mund të përfshijnë_role me with_items), që sistemi i trajtuesit në Ansible është Turing-complete, që trajtuesit nga përfshirja_role kryqëzohen në një mënyrë kurioze me trajtuesit nga loja, etj. .d. - e gjithë kjo nuk është qartë "bazat").

Edhe pse ekziston një WTF specifike që është në të vërtetë një veçori që duhet të mbani në mend. Nëse detyra juaj është ekzekutuar me delegate_to dhe ka njoftuar, atëherë trajtuesi përkatës ekzekutohet pa delegate_to, d.m.th. në hostin ku është caktuar loja. (Edhe pse mbajtësi, natyrisht, mund të ketë delegate_to Njësoj).

Më vete, dua të them disa fjalë për rolet e ripërdorshme. Para se të shfaqeshin koleksionet, ekzistonte një ide se mund të bësh role universale që mund të jenë ansible-galaxy install dhe shkoi. Punon në të gjitha OS të të gjitha varianteve në të gjitha situatat. Pra, mendimi im: nuk funksionon. Çdo rol me masë include_vars, duke mbështetur 100500 raste, është i dënuar në humnerën e insekteve të qosheve. Ato mund të mbulohen me testime masive, por si me çdo testim, ose ju keni një produkt kartezian të vlerave hyrëse dhe një funksion total, ose keni "skenarë individualë të mbuluar". Mendimi im është se është shumë më mirë nëse roli është linear (kompleksiteti ciklomatik 1).

Sa më pak nëse (të shprehura ose deklarative - në formë when ose formë include_vars sipas grupit të variablave), aq më i mirë është roli. Ndonjëherë duhet të bësh degë, por, e përsëris, sa më pak të jenë, aq më mirë. Pra duket si një rol i mirë me galaktikën (funksionon!) me një tufë when mund të jetë më pak i preferueshëm se roli i "vetë" nga pesë detyra. Momenti kur roli me galaktikën është më i mirë është kur fillon të shkruash diçka. Momenti kur përkeqësohet është kur diçka prishet dhe dyshoni se është për shkak të "rolit me galaktikën". Ju e hapni atë dhe ka pesë përfshirje, tetë fletë detyrash dhe një pirg when'ov... Dhe ne duhet ta kuptojmë këtë. Në vend të 5 detyrave, një listë lineare në të cilën nuk ka asgjë për të thyer.

Në pjesët e mëposhtme

  • Pak për inventarin, variablat e grupit, shtojcën host_group_vars, hostvars. Si të lidhni një nyjë gordiane me spageti. Variablat e fushës dhe përparësisë, modeli i memories Ansible. "Pra, ku e ruajmë emrin e përdoruesit për bazën e të dhënave?"
  • jinja: {{ jinja }} — nosql notype nosense plastelinë e butë. Është kudo, edhe aty ku nuk e pret. Pak për !!unsafe dhe yaml e shijshme.

Burimi: www.habr.com

Shto një koment