Grunderna i Ansible som gör att dina playbooks inte bara blir en klump av ihopklibbade makaroner

Jag gör mĂ„nga recensioner av andras kod pĂ„ Ansible och skriver mycket sjĂ€lv. Vid analysen av fel (bĂ„de andras och mina egna), samt genom vissa intervjuer, förstod jag det huvudfel som Ansible-anvĂ€ndare gör — de ger sig in i det komplexa innan de bemĂ€strar grunderna.

För att rÀtta till denna universella orÀttvisa har jag beslutat att skriva en introduktion till Ansible för dem som redan kÀnner till det. Jag varnar, det Àr ingen sammanfattning av manualer, det Àr en lÄng text med mycket text och inga bilder.

Den förvÀntade nivÄn pÄ lÀsaren Àr att ni redan har skrivit flera tusen rader YAML, har nÄgot i produktion, men "det verkar bara snett".

Titlar

Det största misstaget hos Ansible-anvÀndare Àr att inte veta vad saker heter. Om du inte vet namnen kan du inte förstÄ vad som stÄr i dokumentationen. Ett levande exempel: vid en intervju, en person som pÄstod sig ha skrivit mycket i Ansible, kunde inte svara pÄ frÄgan "av vilka element bestÄr en playbook?". NÀr jag pÄpekade att "det förvÀntades ett svar att playbook bestÄr av play", följde en förödande kommentar "vi anvÀnder inte det". MÀnniskor skriver pÄ Ansible för pengar och anvÀnder inte play. De anvÀnder det i sjÀlva verket, men vet inte vad det Àr.

SÄ vi börjar med det enkla: hur saker heter. Kanske vet du detta, eller kanske inte, för att du inte har varit uppmÀrksam nÀr du lÀste dokumentationen.

ansible-playbook kör playbooken. Playbook Àr en fil med Àndelsen yml/yaml, inuti finns nÄgot sÄdant:

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

Vi har redan förstÄtt att hela den hÀr filen Àr en playbook. Vi kan visa var roller (roles) och uppgifter (tasks) finns. Men var Àr play? Och vad skiljer play frÄn role eller playbook?

Detta finns allt i dokumentationen. Och detta missar man. Nybörjare – för att det Ă€r för mycket och man kan inte minnas allt samtidigt. Erfaren – för att "triviala saker". Om du Ă€r erfaren – lĂ€s om dessa sidor Ă„tminstone en gĂ„ng var sjĂ€tte mĂ„nad, och din kod kommer att bli betydligt bĂ€ttre.

SÄ kom ihÄg: Playbook Àr en lista som bestÄr av play och import_playbook.
Detta Àr en play:

- hosts: group1
  roles:
    - role1

och detta Àr ocksÄ en annan play:

- hosts: group2,group3
  tasks:
    - debug:

Vad Àr dÄ en play? Vad behövs den till?

Play Àr en nyckelkomponent för playbook, eftersom en play och endast en play kopplar ihop en lista av roller och/eller uppgifter med en lista av vÀrdar dÀr de ska utföras. I djupet av dokumentationen kan man hitta omnÀmnandet om delegate_to, lokala lookup-plugins, nÀtverks-cli-specifika instÀllningar, hopphostar osv. De tillÄter en lÀtt förÀndring av var uppgifter utförs. Men glöm det. Varje en av dessa smarta alternativ har mycket specifika tillÀmpningar och de Àr definitivt inte universella. Och vi pratar om grundlÀggande saker som alla bör veta och anvÀnda.

Om du vill "göra nĂ„got" "nĂ„gonstans" — skriver du en play. Inte en roll. Inte en roll med moduler och delegater. Du tar och skriver en play. I vilken, i fĂ€ltet hosts, listar du var den ska köras, och i roles/tasks — vad som ska köras.

Enkel, eller hur? Och hur skulle det kunna vara pÄ nÄgot annat sÀtt?

En av de typiska situationerna nÀr folk vill göra detta utan play, Àr "rollen som konfigurerar allt". Man vill ha en roll som konfigurerar och servern den första typen och servrar av den andra typen.

Ett arketypiskt exempel Ă€r övervakning. Man vill ha en roll för övervakning som konfigurerar övervakningen. Rollen för övervakning tilldelas övervakningshosts (i motsvarande play). Men det visar sig att för att övervaka mĂ„ste vi installera paket pĂ„ de hosts vi övervakar. Varför inte anvĂ€nda delegate? Och vi mĂ„ste ocksĂ„ konfigurera iptables. delegate? Och vi mĂ„ste ocksĂ„ skriva/korrigera konfigurationen för databashanteraren sĂ„ att övervakningen tillĂ„ts. delegate! Och om kreativiteten flödar, kan man göra delegation include_role i en inre loop med en smart filtrering av grupplistan, och inuti include_role kan man Ă€ven göra delegate_to igen. Och sĂ„ fortsĂ€tter det


En god önskan — att ha en enda roll för övervakning som "gör allt" — leder oss till en förödande situation dĂ€r den vanligaste utvĂ€gen Ă€r: skriva om allt frĂ„n början.

Var hĂ€r intrĂ€ffade felet? I det ögonblick du upptĂ€ckte att för att utföra uppgiften "x" pĂ„ vĂ€rden X mĂ„ste du gĂ„ till vĂ€rden Y och göra "y" dĂ€r, borde du ha utfört en enkel övning: gĂ„ och skriv en play som pĂ„ vĂ€rden Y gör y. Inte lĂ€gga till nĂ„got i "x", utan skriva frĂ„n början. Även om du hĂ„rdkodar variabler.

Det verkar som att allt ovanstÄende Àr korrekt. Men det Àr inte ditt fall! Eftersom du vill skriva ÄteranvÀndbar kod som Àr DRY och liknar ett bibliotek, och du behöver hitta en metod för att göra det.

HÀr finns en annan allvarlig bugg. En bugg som har förvandlat mÄnga projekt frÄn att vara hyfsat skrivna (det kan bli bÀttre, men allt fungerar och Àr lÀtt att bygga pÄ) till en fullstÀndig mardröm, dÀr till och med författaren har svÄrt att förstÄ. Det fungerar, men Gud förbjude att förÀndra nÄgot.

Denna bugg lÄter sÄ hÀr: en roll Àr en biblioteksfunktion. Denna analoga jÀmförelse har dödat sÄ mÄnga bra initiativ att det Àr sorgligt att se. En roll Àr inte en biblioteksfunktion. Den kan inte göra berÀkningar och den kan inte fatta beslut pÄ nivÄ med play. PÄminn mig, vilka beslut fattar play?

Tack, du har rÀtt. Play fattar ett beslut (mer exakt, innehÄller information) om vilka uppgifter och roller som ska utföras pÄ vilka vÀrdar.

Om du delegerar detta beslut till en roll, och dessutom med berÀkningar, fördömer du dig sjÀlv (och den som kommer att försöka förstÄ din kod) till ett elÀndigt liv. En roll avgör inte var den ska utföras. Det beslutet fattar play. En roll gör det som den blivit tillsagd att göra, dÀr den blivit tillsagd att göra det.

Varför det Àr farligt att programmera med Ansible och varför COBOL Àr bÀttre Àn Ansible kommer vi att diskutera i kapitlet om variabler och jinja. Men just nu kan vi sÀga en sak - varje berÀkning du gör efterlÀmnar ett bestÄende spÄr av förÀndring av globala variabler, och du kan inte göra nÄgot Ät det. SÄ snart tvÄ "spÄr" korsar varandra - allt Àr förlorat.

En notis för den petiga: en roll kan sjÀlvfallet pÄverka kontrollflödet. Det finns delegate_to och det finns rimliga tillÀmpningar för det. Det finns meta: end host/play. Men! Kom ihÄg, vi lÀr oss grunderna? Glömde du bort delegate_to. Vi pratar om den enklaste och vackraste koden i Ansible. Som Àr lÀtt att lÀsa, skriva, felsöka, testa och bygga pÄ. SÄ, Àn en gÄng:

play och endast play avgör pÄ vilka vÀrdar saker körs.

I detta avsnitt har vi granskat motstÄndet mellan play och roll. Nu ska vi prata om relationerna mellan tasks vs roll.

Uppgifter och Roller

LÄt oss betrakta play:

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

LÄt oss sÀga att du behöver göra foo. Och det ser ut som foo: name=foobar state=present. Vart ska detta skrivas? I pre? Post? Ska jag skapa en roll?


 Och vart tog uppgifterna vÀgen?

Vi börjar igen frÄn grunden - strukturen för play. Om du har problem med detta Àmne kan du inte anvÀnda play som grund för allt annat, och ditt resultat blir "skakigt".

Enheten play: direktiv hosts, instÀllningar för sjÀlva play och sektionerna pre_tasks, tasks, roles, post_tasks. Andra parametrar för play Àr för tillfÀllet ointressanta.

Ordningen av deras sektioner med tasker och roller: pre_tasks, roles, tasks, post_tasks. Eftersom den semantiska ordningen för utförandet Àr tasks och roles oklar, sÄ sÀger best practices att vi lÀgger till en sektion tasks, endast om det inte finns nÄgon roles. Om det finns roles, sÄ placeras alla relaterade tasks i sektionerna pre_tasks/post_tasks.

Det kvarstÄr bara det som Àr semantiskt tydligt: först pre_tasks, sedan roles, sedan post_tasks.

Men vi har fortfarande inte besvarat frĂ„gan: var ska vi skriva anropet till modulen foo ? MĂ„ste vi skriva en hel roll för varje modul? Eller Ă€r det bĂ€ttre att ha en allomfattande roll för allt? Och om det inte Ă€r en roll, var skriver vi dĂ„ — i pre eller i post?

Om det inte finns nÄgot vÀlinformerat svar pÄ dessa frÄgor, sÄ Àr det ett tecken pÄ bristande intuition, det vill sÀga de "skakiga grunderna". LÄt oss reda ut det. Först en kontrollfrÄga: Om play har pre_tasks och post_tasks och det inte finns nÄgra tasks eller roller, kan nÄgot gÄ sönder om jag flyttar första tasken frÄn post_tasks till slutet? pre_tasks?

SjÀlvklart antyder formuleringen av frÄgan att nÄgot kommer att gÄ fel. Men vad exakt?


 Handlers. Att lĂ€sa grunderna avslöjar en viktig fakta: alla handlers flushas automatiskt efter varje sektion. Det vill sĂ€ga, alla tasks frĂ„n pre_tasks, körs, dĂ€refter alla handlers som har notifierats. Sedan körs alla roller och alla handlers som har notifierats i rollerna. DĂ€refter post_tasks och deras handlers.

SÄledes, om du flyttar en task frÄn post_tasks pÄ pre_tasks, kan du potentiellt köra den före handlern. Till exempel, om i pre_tasks installationen och konfigurationen webbserver, och i post_tasks nÄgonting skickas, kommer flytten av den hÀr tasken till sektionen pre_tasks att leda till att servern inte Àr igÄng vid "skickande"-tillfÀllet och allt gÄr fel.

Och nu lĂ„t oss tĂ€nka en gĂ„ng till, varför behöver vi pre_tasks och post_tasks? ĐĐ°ĐżŃ€ĐžĐŒĐ”Ń€, ĐŽĐ»Ń Ń‚ĐŸĐłĐŸ, Ń‡Ń‚ĐŸĐ±Ń‹ ĐČŃ‹ĐżĐŸĐ»ĐœĐžŃ‚ŃŒ ĐČсё ĐœŃƒĐ¶ĐœĐŸĐ” (ĐČĐșĐ»ŃŽŃ‡Đ°Ń Ń…ŃĐœĐŽĐ»Đ”Ń€Ń‹) ĐŽĐŸ ĐČŃ‹ĐżĐŸĐ»ĐœĐ”ĐœĐžŃ Ń€ĐŸĐ»Đž. А post_tasks som gör att vi kan arbeta med resultaten frĂ„n rollernas (inklusive handlers) utförande.

En nitisk kĂ€nnare av Ansible kommer att sĂ€ga oss att det finns meta: flush_handlers, men varför behöver vi flush_handlers, om vi kan lita pĂ„ sektionernas utförande ordning i play? Dessutom kan anvĂ€ndningen av meta: flush_handlers ge oss ovĂ€ntade resultat med upprepande handlers och ge oss konstiga varningar vid anvĂ€ndning av when för block osv. Ju mer du kĂ€nner till Ansible, desto fler nyanser kan du namnge för den "fiffiga" lösningen. En enkel lösning — anvĂ€ndningen av naturlig separation mellan pre/roller/post — ger inga nyanser.

Och vi ÄtervÀnder till vÄrt 'foo'. Var ska vi placera det? I pre, post eller i roles? SjÀlvklart beror det pÄ om vi behöver resultaten frÄn handlÀggaren för foo. Om vi inte gör det, sÄ behöver foo inte placeras varken i pre eller post - dessa sektioner har en speciell betydelse - att utföra uppgifter före och efter huvudkoden.

Nu reduceras svaret pÄ frÄgan "roll eller uppgift" till vad som redan finns i play - om det finns uppgifter dÀr, sÄ bör vi lÀgga till dem i tasks. Om det finns roller - sÄ bör vi skapa en roll (Àven om det bara Àr en uppgift). Jag pÄminner om att uppgifter och roller inte anvÀnds samtidigt.

Att förstÄ grunderna i Ansible ger vÀlgrundade svar pÄ frÄgor som verkar handla om smak.

Uppgifter och roller (del tvÄ)

LĂ„t oss nu diskutera situationen nĂ€r du just börjar skriva en playbook. Du behöver göra foo, bar och baz. Är det tre uppgifter, en roll eller tre roller? För att sammanfatta frĂ„gan: nĂ€r bör man börja skriva roller? Vad Ă€r poĂ€ngen med att skriva roller nĂ€r man kan skriva uppgifter?
 Och vad Ă€r en roll?

Ett av de största misstagen (jag har redan pratat om detta) Àr att tro att en roll Àr som en funktion i ett programbibliotek. Hur ser en allmÀn beskrivning av en funktion ut? Den tar in argument, interagerar med sidorelaterade orsaker, skapar bieffekter och returnerar ett vÀrde.

Nu, uppmÀrksamhet. Vad av detta kan göras i en roll? Att skapa bieffekter - alltid gÀrna, det Àr hela syftet med Ansible - att skapa bieffekter. Att ha sidorelaterade orsaker? LÀtt. Men med "skicka ett vÀrde och returnera det" - hÀr Àr det stopp. För det första kan du inte skicka ett vÀrde till en roll. Du kan sÀtta en global variabel med livslÀngd motsvarande play i sektionen vars för rollen. Du kan sÀtta en global variabel med livslÀngd i play inom rollen. Eller till och med med livslÀngd för playbook.set_fact/registerMen du kan inte ha "lokala variabler". Du kan inte "ta emot ett vÀrde" och "returnera det".

Detta leder till den viktigaste punkten: man kan inte skriva nÄgot i Ansible utan att skapa bieffekter. Att Àndra globala variabler Àr alltid en bieffekt för funktionen. I Rust, till exempel, Àr förÀndring av en global variabel - unsafe. Men i Ansible Àr det den enda metoden för att pÄverka vÀrdena för en roll. Observera de anvÀnda orden: inte "skicka ett vÀrde till rollen", utan "Àndra de vÀrden som rollen anvÀnder". Det finns ingen isolering mellan roller. Det finns ingen isolering mellan uppgifter och roller.

Totalt: en roll Àr inte en funktion.

Vad Àr bra med en roll? För det första har en roll standardvÀrden (/default/main.yaml), för det andra har en roll ytterligare kataloger för att lagra filer.

Vad Ă€r bra med standardvĂ€rden? De Ă€r att i Maslows ganska snedvridna hierarki av variabler prioriterade hos Ansible, Ă€r rollstandarder de minst prioriterade (förutom parameterarna frĂ„n Ansible kommandoraden). Det innebĂ€r att om du behöver tillhandahĂ„lla standardvĂ€rden och inte oroa dig för att de ska överskrida vĂ€rden frĂ„n inventariet eller gruppvariabler, sĂ„ Ă€r rollernas standarder det enda rĂ€tta stĂ€llet för dig. (Jag ljuger lite — det finns ocksĂ„ |d(your_default_here), men om vi pratar om stationĂ€ra platser — sĂ„ Ă€r det endast rollernas standarder).

Vad mer Ă€r bra med roller? Det Ă€r att de har sina egna kataloger. Dessa Ă€r kataloger för variabler, bĂ„de permanenta (dvs. de som berĂ€knas för rollen) och dynamiska (det finns ett slags antingen mönster eller anti-mönster — include_vars tillsammans med {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Dessa Ă€r kataloger för files/, templates/. Dessutom tillĂ„ter det roller att ha sina egna moduler och plugins (library/). Men, i jĂ€mförelse med uppgifter i playbooken (som ocksĂ„ kan ha allt detta), Ă€r fördelen hĂ€r bara att filerna inte ligger i en enda hög, utan i flera separata högar.

En annan detalj: man kan försöka skapa roller som kommer att vara tillgÀngliga för ÄteranvÀndning (via galaxy). Efter att samlingar har lanserats kan spridningen av roller nÀstan betraktas som glömd.

SÄledes har roller tvÄ viktiga egenskaper: de har standarder (en unik egenskap) och de tillÄter att strukturera koden.

Återkommande till den ursprungliga frĂ„gan: nĂ€r ska man göra uppgifter och nĂ€r roller? Uppgifter i playbooken anvĂ€nds oftast antingen som "lim" före/efter roller eller som sjĂ€lvstĂ€ndiga byggstenar (dĂ„ bör det inte finnas nĂ„gra roller i koden). En hög av normala uppgifter blandat med roller — det Ă€r helt klart slarvigt. Man bör hĂ„lla sig till en konkret stil — antingen uppgifter eller roller. Roller ger separation av entiteter och standarder, uppgifter gör att man kan lĂ€sa koden snabbare. Vanligtvis förs mer "stationĂ€r" (viktig och komplex) kod ut till roller, medan hjĂ€lpskript skrivs i stil med uppgifter.

Det finns möjlighet att göra import_role som en uppgift, men om du skriver nÄgot sÄdant, var beredd att förklara varför du vill göra detta för ditt eget estetiska sinne.

En pĂ„trĂ€ngande lĂ€sare kan sĂ€ga att roller kan importera roller, att roller kan ha beroenden genom galaxy.yml, och att det finns nĂ„got lĂ€skigt och hemskt. include_role — jag pĂ„minner om att vi förbĂ€ttrar vĂ„ra fĂ€rdigheter i grundlĂ€ggande Ansible, inte i rytmisk gymnastik.

Handlers och uppgifter

LÄt oss diskutera en till uppenbar sak: handlers. Att anvÀnda dem korrekt Àr nÀstan en konst. Vad Àr skillnaden mellan en handler och en uppgift?

Eftersom vi gÄr igenom grunderna, hÀr Àr ett exempel:

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

I en roll ligger handlers i rolename/handlers/main.yaml. Handlers delas mellan alla deltagare i spelet: pre/post_tasks kan aktivera handlers frÄn rollen, och rollen kan anropa handlers frÄn spelet. Men "cross-role" anrop av handlers orsakar en mycket större förvirring Àn att upprepa en trivial handler. (En annan del av bÀsta praxis Àr att försöka undvika att upprepa namn pÄ handlers).

Huvudskillnaden Àr att en uppgift alltid utförs (idempotent) (plus/minus taggar och when), medan en handler utförs beroende pÄ tillstÄndet (notify aktiveras endast om det har skett en förÀndring). Vad kan det leda till? Till exempel, vid en omkörning, om det inte har skett nÄgon förÀndring, kommer inget handler att köras. Men varför kan det vara sÄ att vi behöver utföra en handler nÀr det inte har skett nÄgon förÀndring i den genererande uppgiften? Till exempel, för att nÄgot gick sönder och det skedde en förÀndring, men exekveringen kom inte fram till handler. Till exempel, för att nÀtverket var nere en kort stund. Konfigurationen Àndrades, tjÀnsten startades inte om. Vid nÀsta körning Àndras konfigurationen inte lÀngre, och tjÀnsten förblir med den gamla versionen av konfigurationen.

Situation med konfigurationen Ă€r inte lösbar (eller snarare kan man sjĂ€lva hitta pĂ„ ett speciellt omstartprotokoll med filflaggor osv., men det Ă€r inte lĂ€ngre 'grundlĂ€ggande ansible' i nĂ„got avseende). Men det finns en annan vanlig historia: vi installerade en applikation, antecknade dess .service-fil, och nu vill vi daemon_reload och state=started. Och den naturliga platsen för detta verkar vara en handler. Men om man gör det till en task i slutet av tasklistan eller en roll, sĂ„ kommer den att utföras idempotent varje gĂ„ng. Även om playbooken skulle gĂ„ sönder pĂ„ mitten. Detta löser inte problemet med restarted (man kan inte göra en task med attributet restarted, eftersom idempotensen skulle gĂ„ förlorad), men det Ă€r absolut vĂ€rt att sĂ€tta state=started, den övergripande stabiliteten i playbooks ökar, eftersom antalet kopplingar och dynamiskt tillstĂ„nd minskar.

En annan positiv egenskap hos handlern Ă€r att den inte skrĂ€par ner utskriften. Inga förĂ€ndringar – inga onödiga skipped eller ok i utskriften – lĂ€ttare att lĂ€sa. Det Ă€r ocksĂ„ en negativ egenskap – om du hittar ett stavfel i en linjĂ€rt exekverad task vid första körningen, kommer handlers endast att köras vid Ă€ndringar, det vill sĂ€ga under vissa förutsĂ€ttningar – mycket sĂ€llan. Till exempel första gĂ„ngen i livet efter fem Ă„r. Och naturligtvis kommer det att finnas ett stavfel i namnet och allt kommer att gĂ„ sönder. Vid andra körningen kan de inte startas – det finns ju ingen Ă€ndring.

Man mÄste sÀrskilt nÀmna tillgÄngen till variabler. Till exempel, om du notifierar för en task med en loop, vad kommer att hÀnda med variablerna? Man kan gissa analytiskt, men det Àr inte alltid trivialt, sÀrskilt om variablerna kommer frÄn olika kÀllor.


 SĂ„ handlers Ă€r lĂ„ngt mindre anvĂ€ndbara och mycket mer problematiska Ă€n de verkar. Om man kan skriva nĂ„got snyggt (utan krusiduller) utan handlers, Ă€r det bĂ€ttre att göra det utan dem. Om det inte gĂ„r att fĂ„ det snyggt – Ă€r det bĂ€ttre att anvĂ€nda dem.

Den insiktsfulle lĂ€saren pĂ„pekar med rĂ€tta att vi inte har diskuterat lyssna, att en handler kan anropa notify för en annan handler, att en handler kan innehĂ„lla import_tasks (som kan göra include_role med with_items), att systemet med handlers i Ansible Ă€r turing-komplett, att handlers frĂ„n include_role mĂ€rkligt nog korsas med handlers frĂ„n play och sĂ„ vidare – allt detta Ă€r uppenbarligen inte "grunderna").

Även om det finns ett visst WTF, som faktiskt Ă€r en funktion, och som man mĂ„ste komma ihĂ„g. Om du har en task som körs med delegate_to och den har notify, sĂ„ körs den motsvarande handlern utan delegate_to, det vill sĂ€ga pĂ„ den vĂ€rd dĂ€r play Ă€r tilldelad. (Även om handlern, naturligtvis, kan ha delegate_to ocksĂ„).

Separat vill jag nÀmna nÄgra ord om ÄteranvÀndbara roller. Innan kollektionerna kom fanns det en idé om att man skulle kunna skapa universella roller som kan ansible-galaxy install och sÄ Äkte jag. Fungerar pÄ alla operativsystem i alla varianter i alla situationer. SÄ, min Äsikt: det fungerar inte. Varje roll med stöd för 100500 fall Àr dömd till avgrunder av corner case-buggar. include_varsDe kan tÀppas till med massiv testning, men som med all testning, antingen har du ett kartegiskt produkt av ingÄngsvÀrden och en total funktion, eller sÄ har du "tÀcker enskilda scenarier". Min Äsikt Àr - det Àr mycket bÀttre om rollen Àr linjÀr (cyklomatisk komplexitet 1).

Ju fĂ€rre if:s (öppna eller deklarativa - i form av when eller form include_vars baserat pĂ„ uppsĂ€ttningen av variabler), desto bĂ€ttre Ă€r rollen. Ibland mĂ„ste man göra förgreningar, men, jag upprepar, ju fĂ€rre desto bĂ€ttre. SĂ„ en till synes bra roll med galaxy (den fungerar ju!) med en massa when kan vara mindre önskvĂ€rd Ă€n "sin" roll med fem uppgifter. Momentet nĂ€r rollen med galaxy Ă€r bĂ€ttre - nĂ€r du börjar skriva nĂ„got. Momentet nĂ€r den blir sĂ€mre - nĂ€r nĂ„got gĂ„r sönder, och du har misstankar om att det beror pĂ„ "rollen med galaxy". Du öppnar den, och dĂ€r Ă€r fem inkluderade, Ă„tta uppgiftslistor och en hög when‘or ... Och detta mĂ„ste du reda ut. IstĂ€llet för 5 uppgifter i en linjĂ€r lista, dĂ€r det knappt finns nĂ„got att gĂ„ sönder.

I de följande delarna

  • Lite om inventering, gruppvariabler, host_group_vars-plugin, hostvars. Hur man knyter ihop spagettin till en Gordisk knut. Scope och precedens för variabler, Ansible-minnesmodell. "SĂ„ var ska man egentligen lagra anvĂ€ndarnamnet för databasen?".
  • jinja: {{ jinja }} — nosql notype nonsens mjukt lera. Det finns överallt, Ă€ven dĂ€r du minst anar det. Lite om !!unsafe och lĂ€cker yaml.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster