Ansible bazaĵoj, sen kiuj viaj ludlibroj estos peceto da glueca pasto

Mi faras multajn recenzojn pri la Ansible-kodo de aliuloj kaj mi skribas multe. Dum analizo de eraroj (kaj de aliaj kaj miaj), kaj ankaŭ de kelkaj intervjuoj, mi konstatis la ĉefan eraron, kiun faras uzantoj de Ansible - ili eniras en kompleksajn aferojn sen regi la bazajn.

Por korekti tiun ĉi universalan maljustecon, mi decidis verki enkondukon al Ansible por tiuj, kiuj jam konas ĝin. Mi avertas vin, ĉi tio ne estas rerakonto de viroj, ĉi tio estas longa legaĵo kun multaj leteroj kaj neniuj bildoj.

La atendata nivelo de la leganto estas ke pluraj miloj da linioj de yamla jam estis skribitaj, io jam estas en produktado, sed "iel ĉio estas malrekta."

Titoloj

La ĉefa eraro, kiun Ansible-uzanto faras, estas ne scii, kiel io nomiĝas. Se vi ne konas la nomojn, vi ne povas kompreni, kion diras la dokumentaro. Vivanta ekzemplo: dum intervjuo, persono, kiu ŝajnis diri, ke li multe skribis en Ansible, ne povis respondi la demandon "el kiuj elementoj konsistas ludlibro?" Kaj kiam mi sugestis, ke "la respondo estis atendita, ke la ludlibro konsistas el ludado", sekvis la damna komento "ni ne uzas tion". Homoj skribas Ansible por mono kaj ne uzas ludadon. Ili efektive uzas ĝin, sed ne scias kio ĝi estas.

Do ni komencu per io simpla: kiel ĝi nomiĝas. Eble vi scias ĉi tion, aŭ eble vi ne scias, ĉar vi ne atentis kiam vi legis la dokumentadon.

ansible-playbook ekzekutas la ludlibron. Ludlibro estas dosiero kun la etendaĵo yml/yaml, ene de kiu estas io kiel ĉi tio:

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

Ni jam rimarkis, ke ĉi tiu tuta dosiero estas ludlibro. Ni povas montri kie estas la roloj kaj kie estas la taskoj. Sed kie estas ludado? Kaj kio estas la diferenco inter ludo kaj rolo aŭ ludlibro?

Ĉio estas en la dokumentado. Kaj ili sopiras ĝin. Komencantoj - ĉar estas tro multe kaj vi ne memoros ĉion samtempe. Sperta - ĉar "trivialaj aferoj". Se vi estas sperta, relegu ĉi tiujn paĝojn almenaŭ unufoje ĉiujn ses monatojn, kaj via kodo fariĝos unuaklasa.

Do, memoru: Ludlibro estas listo konsistanta el ludado kaj import_playbook.
Ĉi tio estas unu teatraĵo:

- hosts: group1
  roles:
    - role1

kaj ĉi tio ankaŭ estas alia teatraĵo:

- hosts: group2,group3
  tasks:
    - debug:

Kio estas ludi? Kial ŝi estas?

Ludo estas ŝlosila elemento por ludlibro, ĉar ludado kaj nur ludado asocias liston de roloj kaj/aŭ taskoj kun listo de gastigantoj, sur kiuj ili devas esti ekzekutitaj. En la profundaj profundoj de la dokumentado vi povas trovi mencion pri delegate_to, lokaj serĉaldonaĵoj, ret-cli-specifaj agordoj, saltaj gastigantoj, ktp. Ili permesas vin iomete ŝanĝi la lokon kie taskoj estas plenumitaj. Sed, forgesu pri ĝi. Ĉiu el ĉi tiuj saĝaj elektoj havas tre specifajn uzojn, kaj ili certe ne estas universalaj. Kaj ni parolas pri bazaj aferoj, kiujn ĉiuj devus scii kaj uzi.

Se vi volas plenumi "ion" "ie", vi skribas ludadon. Ne rolo. Ne estas rolo kun moduloj kaj delegitoj. Vi prenas ĝin kaj skribas teatraĵon. En kiu, en la kampo de gastigantoj vi listigas kie ekzekuti, kaj en roloj/taskoj - kion ekzekuti.

Simpla, ĉu ne? Kiel povus esti alie?

Unu el la karakterizaj momentoj, kiam homoj volas fari tion ne per ludado, estas la "rolo, kiu starigas ĉion." Mi ŝatus havi rolon, kiu agordas kaj servilojn de la unua tipo kaj servilojn de la dua tipo.

Arketipa ekzemplo estas monitorado. Mi ŝatus havi monitoran rolon, kiu agordos monitoradon. La monitora rolo estas asignita al monitoraj gastigantoj (laŭ ludado). Sed rezultas, ke por monitorado ni devas liveri pakaĵojn al la gastigantoj, kiujn ni kontrolas. Kial ne uzi delegiton? Vi ankaŭ bezonas agordi iptables. delegito? Vi ankaŭ devas skribi/korekti agordon por la DBMS por ebligi monitoradon. delegito! Kaj se kreemo mankas, tiam vi povas fari delegacion include_role en nestita buklo uzante delikatan filtrilon sur listo de grupoj, kaj interne include_role vi povas fari pli delegate_to denove. Kaj ni foriru...

Bona deziro - havi unu solan monitoran rolon, kiu "ĉion faras" - kondukas nin en kompletan inferon, el kiu plej ofte estas nur unu eliro: reverki ĉion de nulo.

Kie okazis ĉi tie la eraro? En la momento, kiam vi malkovris, ke por fari taskon "x" ĉe gastiganto X, oni devis iri al gastiganto Y kaj fari "y" tie, oni devis fari simplan ekzercon: iri kaj skribi ludadon, kiu ĉe gastiganto Y faras y. Ne aldonu ion al "x", sed skribu ĝin de nulo. Eĉ kun malmolaj variabloj.

Ŝajnas, ke ĉio en la supraj alineoj estas ĝuste dirita. Sed ĉi tio ne estas via kazo! Ĉar vi volas skribi reuzeblan kodon, kiu estas SEKA kaj biblioteksimila, kaj vi devas serĉi metodon pri kiel fari ĝin.

Ĉi tie kaŝiĝas alia grava eraro. Eraro, kiu igis multajn projektojn el tolereble skribitaj (povus esti pli bone, sed ĉio funkcias kaj estas facile fini) en kompletan hororon, kiun eĉ la aŭtoro ne povas eltrovi. Ĝi funkcias, sed Dio gardu vin ŝanĝi ion ajn.

La eraro estas: rolo estas biblioteka funkcio. Ĉi tiu analogio ruinigis tiom da bonaj komencoj, ke estas simple malĝoje rigardi. La rolo ne estas biblioteka funkcio. Ŝi ne povas fari kalkulojn kaj ŝi ne povas fari ludnivelajn decidojn. Memoru al mi kiajn decidojn ludas faras?

Dankon, vi pravas. Ludo faras decidon (pli precize, ĝi enhavas informojn) pri kiuj taskoj kaj roloj plenumi sur kiuj gastigantoj.

Se vi delegas ĉi tiun decidon al rolo, kaj eĉ kun kalkuloj, vi kondamnas vin (kaj tiun, kiu provos analizi vian kodon) al mizera ekzisto. La rolo ne decidas kie ĝi estas farita. Ĉi tiu decido estas farita per ludado. La rolo faras tion, kion ĝi estas rakontita, kie ĝi estas rakontita.

Kial estas danĝere programi en Ansible kaj kial COBOL estas pli bona ol Ansible ni parolos en la ĉapitro pri variabloj kaj jinja. Nuntempe, ni diru unu aferon - ĉiu el viaj kalkuloj postlasas neforviŝeblan spuron de ŝanĝoj en tutmondaj variabloj, kaj vi ne povas fari ion ajn pri tio. Tuj kiam la du "spuroj" intersekciĝis, ĉio malaperis.

Noto por la skermuloj: la rolo certe povas influi la regulfluon. Manĝu delegate_to kaj ĝi havas raciajn uzojn. Manĝu meta: end host/play. Sed! Ĉu vi memoras, ke ni instruas la bazaĵojn? Forgesis pri delegate_to. Ni parolas pri la plej simpla kaj plej bela Ansible-kodo. Kiu estas facile legebla, facile skribi, facile sencimigi, facile provi kaj facile kompletigi. Do, denove:

ludi kaj nur ludi decidas pri kiu gastigas kio estas efektivigita.

En ĉi tiu sekcio, ni traktis la opozicion inter ludo kaj rolo. Nun ni parolu pri la taskoj kontraŭ rola rilato.

Taskoj kaj Roloj

Konsideru ludi:

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

Ni diru, ke vi devas fari foo. Kaj ĝi aspektas kiel foo: name=foobar state=present. Kie mi skribu ĉi tion? en pre? afiŝi? Ĉu krei rolon?

...Kaj kien iris la taskoj?

Ni denove komencas kun la bazaĵoj - la lud-aparato. Se vi flosas pri ĉi tiu afero, vi ne povas uzi ludon kiel bazon por ĉio alia, kaj via rezulto estos "malfirma".

Ludaparato: direktivo de gastigantoj, agordoj por ludado mem kaj antaŭ_taskoj, taskoj, roloj, post_tasksekcioj. La ceteraj parametroj por ludado ne gravas por ni nun.

La ordo de iliaj sekcioj kun taskoj kaj roloj: pre_tasks, roles, tasks, post_tasks. Ĉar semantike la ordo de ekzekuto estas inter tasks и roles ne estas klara, tiam plej bonaj praktikoj diras, ke ni aldonas sekcion tasks, nur se ne roles... Se ekzistas roles, tiam ĉiuj kunaj taskoj estas metitaj en sekciojn pre_tasks/post_tasks.

Restas nur, ke ĉio estas semantike klara: unue pre_taskstiam rolestiam post_tasks.

Sed ni ankoraŭ ne respondis la demandon: kie estas la modulvoko? foo skribi? Ĉu ni bezonas skribi tutan rolon por ĉiu modulo? Aŭ ĉu estas pli bone havi dikan rolon por ĉio? Kaj se ne rolo, do kie mi skribu - en pre aŭ post?

Se ne ekzistas rezonita respondo al ĉi tiuj demandoj, tiam ĉi tio estas signo de manko de intuicio, tio estas, tiuj samaj "ŝanceliĝantaj fundamentoj". Ni eltrovu ĝin. Unue, sekureca demando: Se ludo havas pre_tasks и post_tasks (kaj ne estas taskoj aŭ roloj), tiam io povas rompiĝi, se mi plenumas la unuan taskon de post_tasks Mi movos ĝin ĝis la fino pre_tasks?

Kompreneble, la vortumo de la demando sugestas, ke ĝi rompiĝos. Sed kio precize?

... Pritraktantoj. Legado de la bazaĵoj malkaŝas gravan fakton: ĉiuj pritraktantoj estas aŭtomate forigitaj post ĉiu sekcio. Tiuj. ĉiuj taskoj de pre_tasks, tiam ĉiuj pritraktantoj kiuj estis sciigitaj. Tiam ĉiuj roloj kaj ĉiuj prizorgantoj kiuj estis sciigitaj en la roloj estas ekzekutitaj. Post post_tasks kaj iliaj prizorgantoj.

Tiel, se vi trenas taskon de post_tasks в pre_tasks, tiam eble vi ekzekutos ĝin antaŭ ol la prizorganto estos ekzekutita. ekzemple, se en pre_tasks la retservilo estas instalita kaj agordita, kaj post_tasks io estas sendita al ĝi, tiam transdonu ĉi tiun taskon al la sekcio pre_tasks kondukos al tio, ke en la momento de "sendo" la servilo ankoraŭ ne funkcios kaj ĉio rompiĝos.

Nun ni pensu denove, kial ni bezonas pre_tasks и post_tasks? Ekzemple, por plenumi ĉion necesan (inkluzive de prizorgantoj) antaŭ ol plenumi la rolon. A post_tasks permesos al ni labori kun la rezultoj de ekzekuto de roloj (inkluzive de prizorgantoj).

Sagaca Ansible-fakulo diros al ni, kio ĝi estas. meta: flush_handlers, sed kial ni bezonas flush_handlers se ni povas fidi je la ordo de ekzekuto de sekcioj en ludo? Plie, la uzo de meta: flush_handlers povas doni al ni neatenditajn aferojn kun duplikataj pritraktiloj, donante al ni strangajn avertojn kiam uzataj. when у block ktp. Ju pli bone vi konas la ansible, des pli da nuancoj vi povas nomi por "delikata" solvo. Kaj simpla solvo - uzante naturan dividon inter antaŭ/roloj/post - ne kaŭzas nuancojn.

Kaj, reen al nia 'foo'. Kie mi metu ĝin? En antaŭ, poŝto aŭ roloj? Evidente, tio dependas de ĉu ni bezonas la rezultojn de la prizorganto por foo. Se ili ne estas tie, tiam foo ne bezonas esti metita aŭ antaŭ aŭ post - ĉi tiuj sekcioj havas specialan signifon - plenumante taskojn antaŭ kaj post la ĉefa korpo de kodo.

Nun la respondo al la demando "rolo aŭ tasko" venas al tio, kio jam ludas - se estas taskoj tie, tiam vi devas aldoni ilin al taskoj. Se estas roloj, vi devas krei rolon (eĉ el unu tasko). Mi memorigu al vi, ke taskoj kaj roloj ne estas uzataj samtempe.

Kompreni la bazaĵojn de Ansible provizas raciajn respondojn al ŝajne gusto demandoj.

Taskoj kaj roloj (dua parto)

Nun ni diskutu la situacion, kiam vi ĵus komencas verki ludlibron. Vi devas fari foo, bar kaj baz. Ĉu ĉi tiuj tri taskoj, unu rolo aŭ tri roloj? Por resumi la demandon: je kiu punkto vi komencu verki rolojn? Kio estas la skribo de roloj, kiam oni povas skribi taskojn?... Kio estas rolo?

Unu el la plej grandaj eraroj (mi jam parolis pri tio) estas pensi, ke rolo estas kiel funkcio en la biblioteko de programo. Kiel aspektas ĝenerala funkciopriskribo? Ĝi akceptas enigajn argumentojn, interagas kun kromkaŭzoj, faras kromefikojn kaj redonas valoron.

Nun, atento. Kion oni povas fari el tio en la rolo? Vi ĉiam bonvenigas nomi kromefikojn, ĉi tio estas la esenco de la tuta Ansible - krei kromefikojn. Ĉu flankaj kaŭzoj? Elementa. Sed kun "pasu valoron kaj redonu ĝin" - tie ĝi ne funkcias. Unue, vi ne povas transdoni valoron al rolo. Vi povas agordi tutmondan variablon kun vivdaŭro de ludo en la vars-sekcio por la rolo. Vi povas agordi tutmondan variablon kun vivdaŭro en ludo ene de la rolo. Aŭ eĉ kun la vivdaŭro de ludlibroj (set_fact/register). Sed vi ne povas havi "lokaj variabloj". Vi ne povas "preni valoron" kaj "redoni ĝin".

La ĉefa afero sekvas el tio: vi ne povas skribi ion en Ansible sen kaŭzi kromefikojn. Ŝanĝi tutmondajn variablojn ĉiam estas kromefiko por funkcio. En Rust, ekzemple, ŝanĝi tutmondan variablon estas unsafe. Kaj en Ansible ĝi estas la sola metodo por influi la valorojn por rolo. Notu la uzatajn vortojn: ne "pasi valoron al la rolo", sed "ŝanĝu la valorojn, kiujn la rolo uzas". Ne estas izolado inter roloj. Ne estas izolado inter taskoj kaj roloj.

Sumo: rolo ne estas funkcio.

Kio estas bona pri la rolo? Unue, la rolo havas defaŭltajn valorojn (/default/main.yaml), due, la rolo havas pliajn dosierujojn por konservi dosierojn.

Kio estas la avantaĝoj de defaŭltaj valoroj? Ĉar en la piramido de Maslow, la sufiĉe distordita tabelo de variaj prioritatoj de Ansible, rol-defaŭltoj estas la plej malaltprioritaj (minus Ansible komandliniaj parametroj). Ĉi tio signifas, ke se vi bezonas provizi defaŭltajn valorojn kaj ne zorgi pri ili superregado de la valoroj de inventaro aŭ grupaj variabloj, tiam rolaj defaŭltoj estas la sola ĝusta loko por vi. (Mi iom mensogas - estas pli |d(your_default_here), sed se ni parolas pri senmovaj lokoj, tiam nur rolaj defaŭltoj).

Kio alia estas bonega pri la roloj? Ĉar ili havas siajn proprajn katalogojn. Ĉi tiuj estas dosierujoj por variabloj, kaj konstantaj (t.e. kalkulitaj por la rolo) kaj dinamikaj (estas aŭ ŝablono aŭ kontraŭŝablono - include_vars kune kun {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Ĉi tiuj estas la dosierujoj por files/, templates/. Ankaŭ ĝi permesas vin havi viajn proprajn modulojn kaj kromaĵojn (library/). Sed, kompare kun taskoj en ludlibro (kiu ankaŭ povas havi ĉion ĉi), la sola avantaĝo ĉi tie estas, ke la dosieroj ne estas forĵetitaj en unu amason, sed plurajn apartajn amasojn.

Ankoraŭ unu detalo: vi povas provi krei rolojn, kiuj estos disponeblaj por reuzo (per galaksio). Kun la apero de kolektoj, roldistribuo povas esti konsiderita preskaŭ forgesita.

Tiel, roloj havas du gravajn funkciojn: ili havas defaŭltajn (unika funkcio) kaj ili permesas al vi strukturi vian kodon.

Revenante al la originala demando: kiam fari taskojn kaj kiam fari rolojn? Taskoj en ludlibro estas plej ofte uzataj aŭ kiel "gluo" antaŭ/post roloj, aŭ kiel sendependa konstruelemento (tiam ne estu roloj en la kodo). Amaso da normalaj taskoj miksitaj kun roloj estas neambigua maldiligenteco. Vi devus aliĝi al specifa stilo - ĉu tasko aŭ rolo. Roloj provizas apartigon de entoj kaj defaŭltoj, taskoj permesas vin legi kodon pli rapide. Kutime, pli "senmova" (grava kaj kompleksa) kodo estas metita en rolojn, kaj helpmanuskriptoj estas skribitaj en taskostilo.

Eblas fari import_role kiel taskon, sed se vi skribas ĉi tion, tiam estu preta klarigi al via propra beleco kial vi volas fari tion.

Sagaca leganto povas diri, ke roloj povas importi rolojn, roloj povas havi dependecojn per galaxy.yml, kaj estas ankaŭ terura kaj terura. include_role — Mi memorigas al vi, ke ni plibonigas kapablojn en baza Ansible, kaj ne en figura gimnastiko.

Pritraktantoj kaj taskoj

Ni diskutu alian evidentan aferon: pritraktantoj. Scii uzi ilin ĝuste estas preskaŭ arto. Kio estas la diferenco inter prizorganto kaj trenilo?

Ĉar ni memoras la bazaĵojn, jen ekzemplo:

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

La pritraktiloj de la rolo troviĝas en rolename/handlers/main.yaml. Pritraktantoj furaĝas inter ĉiuj ludpartoprenantoj: pre/post_tasks povas tiri rolprizorgantojn, kaj rolo povas tiri prizorgantojn de la teatraĵo. Tamen, "kruc-rolaj" vokoj al pritraktantoj kaŭzas multe pli da wtf ol ripetado de bagatela prizorganto. (Alia elemento de plej bonaj praktikoj estas provi ne ripeti pritraktilnomojn).

La ĉefa diferenco estas, ke la tasko ĉiam estas efektivigita (idempotente) (plus/minus etikedoj kaj when), kaj la prizorganto - per statoŝanĝo (sciigi fajrojn nur se ĝi estis ŝanĝita). Kion ĉi tio signifas? Ekzemple, la fakto, ke kiam vi rekomencas, se ne estis ŝanĝita, tiam ne estos prizorganto. Kial povus esti, ke ni devas ekzekuti prizorganton kiam ne estis ŝanĝo en la genera tasko? Ekzemple, ĉar io rompiĝis kaj ŝanĝiĝis, sed ekzekuto ne atingis la prizorganton. Ekzemple, ĉar la reto provizore malfunkciis. La agordo ŝanĝiĝis, la servo ne estis rekomencita. La venontan fojon kiam vi komencos ĝin, la agordo ne plu ŝanĝiĝas, kaj la servo restas kun la malnova versio de la agordo.

La situacio kun la agordo ne povas esti solvita (pli precize, vi povas mem inventi specialan rekomencprotokolon per dosierflagoj ktp., sed ĉi tio ne plu estas 'baza ansible' en ajna formo). Sed estas alia komuna historio: ni instalis la aplikaĵon, registris ĝin .service-dosiero, kaj nun ni volas ĝin daemon_reload и state=started. Kaj la natura loko por ĉi tio ŝajnas esti la prizorganto. Sed se vi faras ĝin ne prizorganto sed tasko ĉe la fino de taskolisto aŭ rolo, tiam ĝi estos ekzekutita idempotente ĉiufoje. Eĉ se la ludlibro rompiĝis en la mezo. Ĉi tio tute ne solvas la rekomencitan problemon (oni ne povas fari taskon kun la rekomencita atributo, ĉar idempotenco estas perdita), sed certe indas fari stato=komencita, la ĝenerala stabileco de ludlibroj pliiĝas, ĉar la nombro da konektoj kaj dinamika stato malpliiĝas.

Alia pozitiva propraĵo de la prizorganto estas ke ĝi ne ŝtopas la eliron. Estis neniuj ŝanĝoj - neniu ekstra preterpasita aŭ bone en la eligo - pli facile legebla. Ĝi ankaŭ estas negativa posedaĵo - se vi trovas tajperaron en linie efektivigita tasko ĉe la plej unua kuro, tiam la pritraktiloj estos ekzekutitaj nur kiam ŝanĝitaj, t.e. sub iuj kondiĉoj - tre malofte. Ekzemple, unuafoje en mia vivo kvin jarojn poste. Kaj, kompreneble, estos tajperaro en la nomo kaj ĉio rompiĝos. Kaj se vi ne kuras ilin la duan fojon, ne estas ŝanĝita.

Aparte, ni devas paroli pri la havebleco de variabloj. Ekzemple, se vi sciigas taskon per buklo, kio estos en la variabloj? Vi povas diveni analize, sed ĝi ne ĉiam estas bagatela, precipe se la variabloj venas de malsamaj lokoj.

... Do pritraktantoj estas multe malpli utilaj kaj multe pli problemaj ol ili ŝajnas. Se vi povas skribi ion bele (sen frillaĵoj) sen prizorgantoj, estas pli bone fari ĝin sen ili. Se ĝi ne funkcias bele, estas pli bone kun ili.

La koroda leganto prave atentigas, ke ni ne diskutis listenke prizorganto povas voki notify por alia prizorganto, ke prizorganto povas inkluzivi import_tasks (kiu povas fari include_role kun with_items), ke la pritraktilo-sistemo en Ansible estas Turing-completa, ke pritraktantoj de include_role intersekcas en kurioza maniero kun pritraktantoj de ludado, ktp .d. - ĉio ĉi klare ne estas la "bazaĵoj").

Kvankam ekzistas unu specifa WTF, kiu fakte estas trajto, kiun vi devas memori. Se via tasko estas plenumita per delegate_to kaj ĝi havas sciigon, tiam la responda prizorganto estas ekzekutita sen delegate_to, t.e. sur la gastiganto kie ludado estas asignita. (Kvankam la prizorganto, kompreneble, eble havas delegate_to Same).

Aparte mi volas diri kelkajn vortojn pri reuzeblaj roloj. Antaŭ ol kolektoj aperis, estis ideo, ke vi povus fari universalajn rolojn, kiuj povus esti ansible-galaxy install kaj iris. Funkcias sur ĉiuj OS de ĉiuj variantoj en ĉiuj situacioj. Do, mia opinio: ĝi ne funkcias. Ajna rolo kun maso include_vars, поддержкой 100500 случаев обречена на бездны corner case багов. Их можно затыкать массированным тестированием, но как с любым тестированием, либо у вас декартово произведение входных значений и тотальная функция, либо у вас "покрыты отдельные сценарии". Моё мнение — куда лучше, если роль линейная (цикломатическая сложность 1).

Ju malpli da se (eksplicita aŭ deklara - en la formo when aŭ formo include_vars laŭ aro de variabloj), des pli bona estas la rolo. Kelkfoje oni devas fari branĉojn, sed, mi ripetas, ju malpli estas, des pli bone. Do ŝajnas bona rolo kun galaksio (ĝi funkcias!) kun amaso da when povas esti malpli preferinda ol "propra" rolo el kvin taskoj. La momento, kiam la rolo kun galaksio estas pli bona, estas kiam vi komencas skribi ion. La momento, kiam ĝi plimalboniĝas, estas kiam io rompiĝas kaj vi havas suspekton, ke ĝi estas pro la "rolo kun galaksio". Vi malfermas ĝin, kaj estas kvin inkludoj, ok taskofolioj kaj stako when'ov... Kaj ni devas eltrovi ĉi tion. Anstataŭ 5 taskoj, lineara listo en kiu estas nenio por rompi.

En la sekvaj partoj

  • Iom pri inventaro, grupvariabloj, host_group_vars kromaĵo, hostvars. Kiel ligi gordian nodon per spagetoj. Amplekso kaj prioritatvariabloj, Ansible-memormodelo. "Do kie ni konservas la uzantnomon por la datumbazo?"
  • jinja: {{ jinja }} — nosql notype nosense mola plastilo. Ĝi estas ĉie, eĉ kie vi ne atendas ĝin. Iom pri !!unsafe kaj bongusta yaml.

fonto: www.habr.com

Aldoni komenton