Asianmukaiset perusasiat, joita ilman pelikirjasi ovat tahmea pastapala

Teen paljon arvosteluja muiden ihmisten Ansible-koodista ja kirjoitan paljon itse. Analysoidessani virheitä (sekä muiden että omiani) sekä useiden haastattelujen aikana tajusin Ansiblen käyttäjien päävirheen - he joutuvat monimutkaisiin asioihin hallitsematta perusvirheitä.

Korjatakseni tämän yleismaailmallisen epäoikeudenmukaisuuden päätin kirjoittaa Ansiblen johdannon niille, jotka jo tietävät sen. Varoitan teitä, tämä ei ole miesten uudelleenkertomus, tämä on pitkä luku, jossa on paljon kirjaimia ja ei kuvia.

Lukijan odotettu taso on, että yamlaa on jo kirjoitettu useita tuhansia rivejä, jotain on jo tuotannossa, mutta "joskin kaikki on vinossa".

nimet

Suurin virhe, jonka Ansible-käyttäjä tekee, on se, että hän ei tiedä, mitä jotain kutsutaan. Jos et tiedä nimiä, et voi ymmärtää, mitä dokumentaatio sanoo. Elävä esimerkki: haastattelun aikana henkilö, joka näytti kirjoittaneensa paljon Ansiblessa, ei kyennyt vastaamaan kysymykseen "mistä elementeistä leikkikirja koostuu?" Ja kun ehdotin, että "vastausta odotettiin, että pelikirja koostuu leikistä", seurasi kirottava kommentti "emme käytä sitä". Ihmiset kirjoittavat Ansiblea rahasta eivätkä käytä peliä. He todella käyttävät sitä, mutta eivät tiedä mitä se on.

Aloitetaan siis yksinkertaisella: miksi sitä kutsutaan? Ehkä tiedät tämän, tai ehkä et, koska et kiinnittänyt huomiota, kun luit asiakirjoja.

ansible-playbook suorittaa pelikirjan. Pelikirja on tiedosto, jonka laajennus on yml/yaml ja jonka sisällä on jotain tällaista:

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

Ymmärsimme jo, että tämä koko tiedosto on pelikirja. Voimme näyttää missä roolit ovat ja missä tehtävät. Mutta missä leikkiminen on? Ja mitä eroa on näytelmän ja roolin tai leikkikirjan välillä?

Kaikki on asiakirjoissa. Ja he kaipaavat sitä. Aloittelijat - koska niitä on liikaa, etkä muista kaikkea kerralla. Kokenut - koska "tyhmiä asioita". Jos olet kokenut, lue nämä sivut uudelleen vähintään kuuden kuukauden välein, niin koodistasi tulee luokkansa johtava.

Muista siis: Playbook on luettelo, joka koostuu leikistä ja import_playbook.
Tämä on yksi näytelmä:

- hosts: group1
  roles:
    - role1

ja tämä on myös toinen näytelmä:

- hosts: group2,group3
  tasks:
    - debug:

Mitä leikkiminen on? Miksi hän on?

Leikki on pelikirjan avainelementti, koska leikki ja vain leikki liittää luettelon rooleista ja/tai tehtävistä luetteloon isännistä, joissa ne on suoritettava. Dokumentaation syvältä löytyy mainintaa delegate_to, paikalliset hakulaajennukset, verkkokliinkohtaiset asetukset, hyppyisännät jne. Niiden avulla voit muuttaa hieman tehtävien suorittamispaikkaa. Mutta unohda se. Jokaisella näistä älykkäistä vaihtoehdoista on hyvin erityisiä käyttötarkoituksia, eivätkä ne todellakaan ole universaaleja. Ja puhumme perusasioista, jotka kaikkien tulisi tietää ja käyttää.

Jos haluat esittää "jotain" "jossakin", kirjoitat näytelmää. Ei rooli. Ei rooli moduulien ja edustajien kanssa. Ota se ja kirjoita näytelmää. Jossa hosts-kentässä luetellaan suoritettavat kohteet ja rooleissa/tehtävissä - mitä suoritetaan.

Yksinkertaista, eikö? Miten se voisi olla toisin?

Yksi tyypillisistä hetkistä, jolloin ihmisillä on halu tehdä tämä ei leikin kautta, on "rooli, joka asettaa kaiken". Haluaisin roolin, joka määrittää sekä ensimmäisen tyypin palvelimet että toisen tyypin palvelimet.

Arkkityyppinen esimerkki on valvonta. Haluaisin valvontaroolin, joka määrittää valvonnan. Valvontarooli on osoitettu valvoville isännille (pelin mukaan). Mutta käy ilmi, että seurantaa varten meidän on toimitettava paketit valvomillemme isännille. Mikset käytä delegaattia? Sinun on myös määritettävä iptables. delegoida? Sinun on myös kirjoitettava/korjattava DBMS:n konfiguraatio valvonnan mahdollistamiseksi. delegoida! Ja jos luovuus puuttuu, voit tehdä valtuuskunnan include_role sisäkkäisessä silmukassa käyttämällä hankalaa suodatinta ryhmäluettelossa ja sisällä include_role voit tehdä enemmän delegate_to uudelleen. Ja pois mennään...

Hyvä toive - yksi ainoa valvontarooli, joka "tekee kaiken" - johtaa meidät täydelliseen helvettiin, josta useimmiten on vain yksi tie: kirjoittaa kaikki uudelleen tyhjästä.

Missä tässä on tapahtunut virhe? Sillä hetkellä, kun huomasit, että tehdäksesi tehtävän "x" isännällä X, sinun oli mentävä isännälle Y ja tehtävä "y" siellä, sinun täytyi tehdä yksinkertainen harjoitus: mennä ja kirjoittaa toisto, mikä isännässä Y tekee y:n. Älä lisää "x:ään" mitään, vaan kirjoita se tyhjästä. Jopa kovakoodattujen muuttujien kanssa.

Näyttää siltä, ​​​​että kaikki yllä olevissa kappaleissa on sanottu oikein. Mutta tämä ei ole sinun tapauksesi! Koska haluat kirjoittaa uudelleen käytettävää koodia, joka on KUIVAA ja kirjastomaista, ja sinun on etsittävä menetelmä, kuinka se tehdään.

Tässä piilee toinen vakava virhe. Virhe, joka muutti monet projektit siedettävästi kirjoitetusta (voisi olla parempikin, mutta kaikki toimii ja on helppo viimeistellä) täydelliseksi kauhuksi, jota edes kirjoittaja ei voi käsittää. Se toimii, mutta Jumala varjelkoon muuttamasta mitään.

Virhe on: rooli on kirjastotoiminto. Tämä analogia on pilannut niin monta hyvää alkua, että sitä on yksinkertaisesti surullista katsoa. Rooli ei ole kirjastotoiminto. Hän ei osaa laskea eikä tehdä pelitason päätöksiä. Muistuta minua, mitä päätöksiä leikki tekee?

Kiitos, olet oikeassa. Play tekee päätöksen (tarkemmin sanottuna se sisältää tietoa) siitä, mitä tehtäviä ja rooleja suorittaa missä isännissä.

Jos delegoit tämän päätöksen roolille ja jopa laskelmilla, tuomitset itsesi (ja sen, joka yrittää jäsentää koodisi) surkeaan elämään. Rooli ei päätä missä se suoritetaan. Tämä päätös tehdään pelaamalla. Rooli tekee mitä käsketään, missä käsketään.

Miksi on vaarallista ohjelmoida Ansiblella ja miksi COBOL on parempi kuin Ansible, puhumme muuttujista ja jinjasta luvussa. Sanotaan nyt yksi asia - jokainen laskelmasi jättää jälkeensä lähtemättömän jäljen globaalien muuttujien muutoksista, etkä voi tehdä asialle mitään. Heti kun kaksi "jälkeä" leikkaavat, kaikki oli poissa.

Huomio kiukkuisille: rooli voi varmasti vaikuttaa ohjausvirtaan. Syödä delegate_to ja sillä on järkevää käyttöä. Syödä meta: end host/play. Mutta! Muistatko, että opetamme perusasiat? Unohtui delegate_to. Puhumme yksinkertaisimmasta ja kauneimmasta Ansible-koodista. Joka on helppo lukea, helppo kirjoittaa, helppo debug, helppo testata ja helppo suorittaa. Eli vielä kerran:

pelata ja vain peli päättää, mitkä isännät mitä suoritetaan.

Tässä osiossa käsittelimme leikin ja roolin vastakohtaa. Puhutaanpa nyt tehtävien ja roolien suhteesta.

Tehtävät ja roolit

Harkitse pelaamista:

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

Oletetaan, että sinun täytyy tehdä foo. Ja siltä näyttää foo: name=foobar state=present. Minne tämä pitäisi kirjoittaa? ennen? lähettää? Luoda rooli?

...Ja mihin tehtävät menivät?

Aloitamme jälleen perusasioista - pelilaitteesta. Jos leijut tässä asiassa, et voi käyttää pelaamista kaiken muun perustana, ja tuloksesi on "heiluva".

Toistolaite: hosts-direktiivi, itse pelin asetukset ja pre_tasks, tehtävät, roolit, post_tasks -osiot. Muut peliparametrit eivät ole meille tärkeitä nyt.

Niiden osioiden järjestys tehtävineen ja rooleineen: pre_tasks, roles, tasks, post_tasks. Koska semanttisesti suoritusjärjestys on välillä tasks и roles ei ole selvää, parhaat käytännöt sanovat, että lisäämme osion tasks, vain jos ei roles... Jos on roles, sitten kaikki liitetyt tehtävät sijoitetaan osiin pre_tasks/post_tasks.

Jäljelle jää vain, että kaikki on semanttisesti selvää: ensin pre_tasks, sitten roles, sitten post_tasks.

Mutta emme ole vieläkään vastanneet kysymykseen: missä on moduulikutsu? foo kirjoittaa? Onko meidän kirjoitettava koko rooli jokaiselle moduulille? Vai onko parempi olla paksu rooli kaikessa? Ja jos ei roolia, niin minne minun pitäisi kirjoittaa - ennen tai postausta?

Jos näihin kysymyksiin ei ole perusteltua vastausta, tämä on merkki intuition puutteesta, toisin sanoen samoista "härkäisistä perustaista". Selvitetään se. Ensinnäkin turvakysymys: Jos pelissä on pre_tasks и post_tasks (eikä tehtäviä tai rooleja ole), niin voiko jotain katketa, jos suoritan ensimmäisen tehtävän post_tasks Siirrän sen loppuun pre_tasks?

Tietenkin kysymyksen sanamuoto vihjaa, että se rikkoutuu. Mutta mitä tarkalleen?

... Käsittelijät. Perusasioiden lukeminen paljastaa tärkeän tosiasian: kaikki käsittelijät huuhdellaan automaattisesti jokaisen osan jälkeen. Nuo. kaikki tehtävät alkaen pre_tasks, sitten kaikki käsittelijät, joille on ilmoitettu. Sitten kaikki roolit ja kaikki käsittelijät, jotka on ilmoitettu rooleissa, suoritetaan. Jälkeen post_tasks ja heidän hoitajiaan.

Jos siis vedät tehtävän kohteesta post_tasks в pre_tasks, sitten mahdollisesti suoritat sen ennen kuin käsittelijä suoritetaan. esimerkiksi jos sisään pre_tasks web-palvelin on asennettu ja määritetty, ja post_tasks sille lähetetään jotain, siirrä sitten tämä tehtävä osioon pre_tasks johtaa siihen, että lähetyshetkellä palvelin ei ole vielä käynnissä ja kaikki hajoaa.

Mietitään nyt uudestaan, miksi sitä tarvitaan pre_tasks и post_tasks? Esimerkiksi saadakseen kaiken tarpeellisen (mukaan lukien käsittelijät) valmiiksi ennen roolin täyttämistä. A post_tasks antaa meille mahdollisuuden työskennellä roolien suorittamisen tulosten kanssa (mukaan lukien käsittelijät).

Viisas Ansible-asiantuntija kertoo meille, mikä se on. meta: flush_handlers, mutta miksi tarvitsemme flush_handlereita, jos voimme luottaa pelissä olevien osien suoritusjärjestykseen? Lisäksi metan käyttö: flush_handlers voi antaa meille odottamattomia asioita päällekkäisten käsittelijöiden kanssa, mikä antaa meille outoja varoituksia käytettäessä when у block jne. Mitä paremmin tunnet mahdollisen, sitä enemmän vivahteita voit nimetä "mutkaiselle" ratkaisulle. Ja yksinkertainen ratkaisu - käyttämällä luonnollista jakoa esi/roolien/post välillä - ei aiheuta vivahteita.

Ja takaisin "foo":han. Mihin se pitäisi laittaa? Ennen, postitse vai rooleissa? Ilmeisesti tämä riippuu siitä, tarvitsemmeko foo-käsittelijän tuloksia. Jos niitä ei ole, foo ei tarvitse sijoittaa pre- tai post-kohtaan - näillä osioilla on erityinen merkitys - suorittamaan tehtäviä ennen ja jälkeen koodin pääosan.

Nyt vastaus kysymykseen "rooli tai tehtävä" tulee siihen, mikä on jo pelissä - jos siellä on tehtäviä, sinun on lisättävä ne tehtäviin. Jos rooleja on, sinun on luotava rooli (jopa yhdestä tehtävästä). Haluan muistuttaa, että tehtäviä ja rooleja ei käytetä samanaikaisesti.

Ansiblen perusteiden ymmärtäminen antaa järkeviä vastauksia näennäisesti makukysymyksiin.

Tehtävät ja roolit (osa kaksi)

Keskustellaan nyt tilanteesta, kun olet vasta aloittamassa leikkikirjan kirjoittamista. Sinun täytyy tehdä foo, baari ja baz. Ovatko nämä kolme tehtävää, yksi rooli vai kolme roolia? Yhteenvetona kysymykseen: missä vaiheessa sinun pitäisi alkaa kirjoittaa rooleja? Mitä järkeä on kirjoittaa rooleja, kun osaa kirjoittaa tehtäviä?... Mikä on rooli?

Yksi suurimmista virheistä (puhuin jo tästä) on ajatella, että rooli on kuin funktio ohjelman kirjastossa. Miltä yleinen funktiokuvaus näyttää? Se hyväksyy syöteargumentteja, on vuorovaikutuksessa sivusyiden kanssa, tekee sivuvaikutuksia ja palauttaa arvon.

Nyt huomio. Mitä tästä voidaan tehdä roolissa? Olet aina tervetullut kutsumaan sivuvaikutuksia, tämä on koko Ansiblen ydin - sivuvaikutusten luominen. Onko sivusyitä? Perus. Mutta "välitä arvo ja palauta se" - se ei toimi. Ensinnäkin et voi siirtää arvoa roolille. Voit määrittää roolin vars-osiossa globaalin muuttujan, jolla on koko pelin koko. Voit asettaa roolin sisällä globaalin muuttujan, jolla on elinikäinen peli. Tai jopa leikkikirjojen elinkaaren kanssa (set_fact/register). Mutta sinulla ei voi olla "paikallisia muuttujia". Et voi "ottaa arvoa" ja "palauttaa sitä".

Pääasia seuraa tästä: et voi kirjoittaa mitään Ansibleen aiheuttamatta sivuvaikutuksia. Globaalien muuttujien muuttaminen on aina sivuvaikutus funktiolle. Esimerkiksi Rustissa globaalin muuttujan muuttaminen on unsafe. Ja Ansiblessa se on ainoa tapa vaikuttaa roolin arvoihin. Huomaa käytetyt sanat: ei "välitä arvoa roolille", vaan "muuta roolin käyttämiä arvoja". Roolien välillä ei ole eristäytymistä. Tehtävien ja roolien välillä ei ole eristäytymistä.

Yhteensä: rooli ei ole toiminto.

Mitä hyvää roolissa on? Ensinnäkin roolilla on oletusarvot (/default/main.yaml), toiseksi roolissa on lisähakemistoja tiedostojen tallentamista varten.

Mitä etuja oletusarvoista on? Koska Maslow'n pyramidissa, Ansiblen melko kieroutuneessa muuttuvien prioriteettien taulukossa, roolioletukset ovat kaikkein alhaisimpia (miinus Ansible-komentoriviparametrit). Tämä tarkoittaa, että jos sinun on annettava oletusarvot etkä ole huolissasi siitä, että ne ohittavat varasto- tai ryhmämuuttujien arvot, roolioletukset ovat ainoa oikea paikka sinulle. (Valehtelen vähän - niitä on enemmän |d(your_default_here), mutta jos puhumme kiinteistä paikoista, niin vain roolioletukset).

Mitä muuta rooleissa on hienoa? Koska heillä on omat luettelonsa. Nämä ovat hakemistoja muuttujille, sekä vakioille (eli laskettu roolille) että dynaamisille (on joko kuvio tai anti-kuvio - include_vars kanssa {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Nämä ovat hakemistoja files/, templates/. Sen avulla voit myös käyttää omia moduuleja ja laajennuksia (library/). Mutta verrattuna leikkikirjan tehtäviin (jossa voi myös olla kaikki tämä), ainoa etu tässä on, että tiedostoja ei upota yhteen pinoon, vaan useisiin erillisiin pinoihin.

Vielä yksi yksityiskohta: voit yrittää luoda rooleja, jotka ovat käytettävissä uudelleen (galaksin kautta). Kokoelmien myötä roolijako voidaan pitää melkein unohdettuina.

Näin ollen rooleilla on kaksi tärkeää ominaisuutta: niillä on oletusarvot (ainutlaatuinen ominaisuus) ja niiden avulla voit jäsentää koodiasi.

Palatakseni alkuperäiseen kysymykseen: milloin tehdä tehtäviä ja milloin tehdä rooleja? Pelikirjan tehtäviä käytetään useimmiten joko "liimana" ennen/jälkeen rooleja tai itsenäisenä rakennuselementtinä (silloin koodissa ei pitäisi olla rooleja). Kasa normaaleja tehtäviä sekoitettuna rooleihin on yksiselitteistä huolimattomuutta. Sinun tulee noudattaa tiettyä tyyliä - joko tehtävää tai roolia. Roolit erottavat entiteetit ja oletukset, tehtävien avulla voit lukea koodia nopeammin. Yleensä "kiinteämpää" (tärkeää ja monimutkaisempaa) koodia laitetaan rooleihin ja apuskriptit kirjoitetaan tehtävätyyliin.

Import_role on mahdollista tehdä tehtävänä, mutta jos kirjoitat tämän, ole valmis selittämään omalle kauneutellesi miksi haluat tehdä tämän.

Viisas lukija voi sanoa, että roolit voivat tuoda rooleja, rooleilla voi olla riippuvuuksia galaxy.yml:n kautta, ja siellä on myös kauhea ja kauhea include_role — Muistutan, että parannamme taitoja Ansiblen peruslajissa, emme vartalovoimistelussa.

Käsittelijät ja tehtävät

Keskustellaan toisesta ilmeisestä asiasta: käsittelijöistä. Niiden oikea käyttö on melkein taidetta. Mitä eroa on ohjaajan ja vedon välillä?

Koska muistamme perusasiat, tässä on esimerkki:

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

Roolin käsittelijät sijaitsevat hakemistossa rolename/handlers/main.yaml. Käsittelijät kurjailevat kaikkien leikin osallistujien välillä: pre/post_tasks voi vetää roolikäsittelijöitä, ja rooli voi vetää ohjaajia leikistä. Kuitenkin "roolien väliset" kutsut käsittelijöille aiheuttavat paljon enemmän wtf:ää kuin triviaalin käsittelijän toistaminen. (Toinen osa parhaita käytäntöjä on yrittää olla toistamatta käsittelijöiden nimiä).

Suurin ero on, että tehtävä suoritetaan aina (idempotently) (plus/miinus tagit ja when), ja käsittelijä - tilan muutoksen mukaan (ilmoita paloista vain, jos sitä on muutettu). Mitä tämä tarkoittaa? Esimerkiksi se, että kun käynnistät uudelleen, jos mitään ei muutettu, käsittelijää ei ole. Miksi meidän on ehkä suoritettava käsittelijä, kun luova tehtävä ei muuttunut? Esimerkiksi siksi, että jokin meni rikki ja muuttui, mutta toteutus ei päässyt käsittelijään. Esimerkiksi koska verkko oli väliaikaisesti poissa käytöstä. Kokoonpano on muuttunut, palvelua ei ole käynnistetty uudelleen. Kun seuraavan kerran käynnistät sen, konfiguraatio ei enää muutu, ja palvelu pysyy konfiguraation vanhassa versiossa.

Tilannetta konfiguroinnin kanssa ei voi ratkaista (tarkemmin sanottuna voit keksiä itsellesi erityisen uudelleenkäynnistysprotokollan tiedostolipuilla jne., mutta tämä ei ole enää 'perusmahdollisuutta' missään muodossa). Mutta on toinenkin yleinen tarina: asensimme sovelluksen, tallensimme sen .service-tiedosto, ja nyt haluamme sen daemon_reload и state=started. Ja luonnollinen paikka tälle näyttää olevan käsittelijä. Mutta jos teet siitä käsittelijän, vaan tehtävän tehtäväluettelon tai roolin lopussa, se suoritetaan täydellisesti joka kerta. Vaikka pelikirja menisi kesken. Tämä ei ratkaise uudelleenkäynnistysongelmaa ollenkaan (restarted-attribuutilla ei voi tehdä tehtävää, koska idempotenssi menetetään), mutta kannattaa ehdottomasti tehdä tila=käynnistetty, pelikirjojen yleinen vakaus kasvaa, koska yhteyksien määrä ja dynaaminen tila vähenevät.

Toinen käsittelijän myönteinen ominaisuus on, että se ei tukki lähtöä. Ei muutoksia - ei ylimääräistä ohitettua tai ok tulosteessa - helpompi lukea. Se on myös negatiivinen ominaisuus - jos huomaat kirjoitusvirheen lineaarisesti suoritetusta tehtävästä heti ensimmäisellä kerralla, käsittelijät suoritetaan vain muutettaessa, ts. joissakin olosuhteissa - hyvin harvoin. Esimerkiksi ensimmäistä kertaa elämässäni viisi vuotta myöhemmin. Ja tietysti nimessä tulee kirjoitusvirhe ja kaikki menee rikki. Ja jos et käytä niitä toisella kerralla, tilanne ei muutu.

Erikseen meidän on puhuttava muuttujien saatavuudesta. Jos esimerkiksi ilmoitat tehtävästä silmukalla, mitä muuttujissa on? Voit arvata analyyttisesti, mutta se ei ole aina triviaalia, varsinkin jos muuttujat tulevat eri paikoista.

... Käsittelijät ovat siis paljon vähemmän hyödyllisiä ja paljon ongelmallisempia kuin miltä ne näyttävät. Jos osaa kirjoittaa jotain kauniisti (ilman röyhelöitä) ilman käsittelijöitä, on parempi tehdä se ilman niitä. Jos se ei toimi kauniisti, on parempi heidän kanssaan.

Syövyttävä lukija huomauttaa aivan oikein, että emme ole keskustelleet listenettä käsittelijä voi kutsua ilmoitusta toiselle käsittelijälle, että käsittelijä voi sisältää import_tasks (joka voi tehdä include_role kanssa with_items), että Ansiblen käsittelijäjärjestelmä on Turing-täydellinen, että käsittelijät kohdasta include_role leikkaavat omituisella tavalla leikin käsittelijöitä, jne. .d. - kaikki tämä ei selvästikään ole "perusasiat").

Vaikka on olemassa yksi tietty WTF, joka on itse asiassa ominaisuus, joka sinun on pidettävä mielessä. Jos tehtäväsi suoritetaan delegate_to ja sillä on ilmoitus, niin vastaava käsittelijä suoritetaan ilman delegate_to, eli isännässä, johon toisto on määritetty. (Vaikka ohjaajalla voi tietysti olla delegate_to Sama).

Haluan erikseen sanoa muutaman sanan uudelleenkäytettävistä rooleista. Ennen kokoelmien ilmestymistä oli ajatus, että voit tehdä universaaleja rooleja, joita voisi olla ansible-galaxy install ja meni. Toimii kaikkien versioiden kaikissa käyttöjärjestelmissä kaikissa tilanteissa. Joten mielipiteeni: se ei toimi. Mikä tahansa rooli massalla include_vars, joka tukee 100500 1 tapausta, on tuomittu kulmakotelovirheiden kuiluun. Ne voidaan kattaa massiivisella testauksella, mutta kuten missä tahansa testauksessa, sinulla on joko syötearvojen ja kokonaisfunktion karteesinen tulo tai "yksittäiset skenaariot". Mielestäni on paljon parempi, jos rooli on lineaarinen (syklomaattinen kompleksisuus XNUMX).

Mitä vähemmän jos-merkkejä (eksplisiittisiä tai deklaratiivisia - muodossa when tai muotoa include_vars muuttujajoukon mukaan), sitä parempi rooli. Joskus on tehtävä oksia, mutta toistan, että mitä vähemmän niitä on, sen parempi. Joten se näyttää hyvältä roolilta galaxyn kanssa (se toimii!) joukon kanssa when voi olla vähemmän parempi kuin "oma" rooli viidestä tehtävästä. Hetki, jolloin rooli galaxyn kanssa on parempi, on silloin, kun alkaa kirjoittaa jotain. Hetki, jolloin se pahenee, on silloin, kun jokin rikkoutuu ja sinulla on epäilys, että se johtuu "roolista galaksin kanssa". Avaat sen, ja siinä on viisi inkluusiota, kahdeksan tehtäväarkkia ja pino when'ov... Ja meidän täytyy selvittää tämä. 5 tehtävän sijaan lineaarinen lista, jossa ei ole mitään rikkomista.

Seuraavissa osissa

  • Hieman varastosta, ryhmämuuttujista, host_group_vars-laajennuksesta, hostvarsista. Kuinka solmia Gordionin solmu spagetin kanssa. Laajuus- ja ensisijaisuusmuuttujat, mahdollinen muistimalli. "Mihin sitten tallennetaan tietokannan käyttäjätunnus?"
  • jinja: {{ jinja }} — nosql notype nosense pehmeä muovailuvaha. Se on kaikkialla, myös siellä, missä et sitä odota. Vähän noin !!unsafe ja herkullista yamlia.

Lähde: will.com

Lisää kommentti