Fra den andre commit, blir enhver kode legacy, fordi de første ideene begynner å avvike fra den harde virkeligheten. Dette er verken bra eller dårlig, det er en gitt som er vanskelig å argumentere med og må leves med. En del av denne prosessen er refaktorisering. Refaktorering av infrastruktur som kode. La historien begynne om hvordan du refaktoriserer Ansible om et år og ikke blir gal.
Arvens fødsel
Dag #1: Pasient Zero
Det var en gang et betinget prosjekt. Den hadde et Dev-utviklingsteam og Ops-ingeniører. De løste det samme problemet: hvordan distribuere servere og kjøre en applikasjon. Problemet var at hvert lag løste dette problemet på sin egen måte. På prosjektet ble det besluttet å bruke Ansible til å synkronisere kunnskap mellom Dev- og Ops-teamene.
Dag #89: Arvens fødsel
Uten å merke det selv ønsket de å gjøre det best mulig, men det viste seg å være arv. Hvordan skjer dette?
Vi har en presserende oppgave her, la oss gjøre et skittent hack og så fikse det.
Du trenger ikke å skrive dokumentasjon og alt er klart hva som skjer her.
Jeg kjenner Ansible/Python/Bash/Terraform! Se hvordan jeg kan unnslippe!
Jeg er en Full Stack Overflow-utvikler og kopierte dette fra stackoverflow, jeg vet ikke hvordan det fungerer, men det ser kult ut og løser problemet.
Som et resultat kan du få en uforståelig type kode som det ikke er dokumentasjon for, det er ikke klart hva den gjør, om den er nødvendig, men problemet er at du må utvikle den, endre den, legge til krykker og støtter , noe som gjør situasjonen enda verre.
Den opprinnelig utformede og implementerte IaC-modellen oppfyller ikke lenger kravene til brukere / bedrifter / andre team, og tiden for å gjøre endringer i infrastrukturen slutter å være akseptabel. I dette øyeblikket kommer forståelsen at det er på tide å ta grep.
IaC-refaktorering
Dag #139: Trenger du virkelig refaktorering?
Før du skynder deg til refaktorisering, må du svare på en rekke viktige spørsmål:
Hvorfor trenger du alt dette?
Har du tid?
Er kunnskap nok?
Hvis du ikke vet hvordan du skal svare på spørsmålene, vil refaktoriseringen avsluttes før den i det hele tatt begynner, eller det kan bare bli verre. Fordi hadde erfaring( Hva jeg lærte av å teste 200 000 linjer med infrastrukturkode), så mottok prosjektet en forespørsel om hjelp til å fikse rollene og dekke dem med tester.
Dag #149: Forbereder refaktoriseringen
Det første er å forberede seg. Bestem hva vi skal gjøre. For å gjøre dette, kommuniserer vi, finner problemområder og finner ut måter å løse dem på. Vi registrerer de resulterende konseptene på en eller annen måte, for eksempel en artikkel i sammenløp, slik at når spørsmålet oppstår "hva er best?" eller "som er riktig?" Vi har ikke mistet veien. I vårt tilfelle holdt vi fast ved ideen dele og herske: vi bryter opp infrastrukturen i små biter/klosser. Denne tilnærmingen lar deg ta et isolert stykke infrastruktur, forstå hva det gjør, dekke det med tester og endre det uten frykt for å ødelegge noe.
Det viser seg at infrastrukturtesting blir hjørnesteinen og her er det verdt å nevne infrastrukturtestpyramiden. Akkurat samme ideen som er under utvikling, men for infrastruktur: vi går fra billige hurtigtester som sjekker enkle ting, som for eksempel innrykk, til dyre fullverdige tester som distribuerer hele infrastrukturen.
Ansible testforsøk
Før vi går for å beskrive hvordan vi dekket Ansible-tester på prosjektet, vil jeg beskrive forsøkene og tilnærmingene som jeg hadde mulighet til å bruke tidligere for å forstå konteksten til beslutningene som ble tatt.
Dag nr. -997: SDS-bestemmelse
Første gang jeg testet Ansible var på et prosjekt for å utvikle SDS (Software Defined Storage). Det er en egen artikkel om dette emnet Hvordan knuse sykler over krykker når du tester distribusjonen din, men kort sagt, vi endte opp med en omvendt testpyramide og testing brukte vi 60-90 minutter på én rolle, som er lang tid. Grunnlaget var e2e-tester, d.v.s. vi distribuerte en fullverdig installasjon og testet den deretter. Det som var enda mer skjerpende var oppfinnelsen av sin egen sykkel. Men jeg må innrømme at denne løsningen fungerte og muliggjorde en stabil utgivelse.
Dag # -701: Ansible og prøvekjøkken
Utviklingen av Ansible-testideen var bruk av ferdige verktøy, nemlig testkjøkken/kjøkken-ci og inspec. Valget ble bestemt av kunnskap om Ruby (for flere detaljer, se artikkelen om Habré: Drømmer YML-programmerere om å teste Ansible?) jobbet raskere, ca 40 minutter for 10 roller. Vi laget en pakke med virtuelle maskiner og kjørte tester inne.
Generelt fungerte løsningen, men det var noe sediment på grunn av heterogenitet. Da antallet personer som ble testet ble økt til 13 grunnleggende roller og 2 metaroller som kombinerte mindre roller, begynte plutselig testene å kjøre i 70 minutter, som er nesten 2 ganger lengre. Det var vanskelig å snakke om XP (ekstrem programmering) praksis fordi... ingen ønsker å vente 70 minutter. Dette var grunnen til å endre tilnærmingen
Dag # -601: Ansible og molekyl
Konseptuelt ligner dette på testkitchen, bare vi flyttet rolletesting til docker og endret stabelen. Som et resultat ble tiden redusert til stabile 20-25 minutter for 7 roller.
Ved å øke antallet testede roller til 17 og lining av 45 roller, kjørte vi dette på 28 minutter på 2 jenkins-slaver.
Dag #167: Legger til Ansible-tester til prosjektet
Mest sannsynlig vil det ikke være mulig å gjøre refaktoriseringsoppgaven i en hast. Oppgaven skal være målbar slik at du kan bryte den i små biter og spise elefanten bit for bit med en teskje. Det må være en forståelse for om du beveger deg i riktig retning, hvor lenge du skal gå.
Generelt spiller det ingen rolle hvordan det skal gjøres, du kan skrive på et stykke papir, du kan sette klistremerker på skapet, du kan lage oppgaver i Jira, eller du kan åpne Google Docs og skrive ned gjeldende status der. Bena vokser av at prosessen ikke er umiddelbar, den blir lang og kjedelig. Det er usannsynlig at noen vil at du skal brenne ut av ideer, bli sliten og bli overveldet under refaktorisering.
Refaktoreringen er enkel:
Spise.
Sov.
Kode.
IaC-test.
Gjenta
og vi gjentar dette til vi når det tiltenkte målet.
Det er kanskje ikke mulig å begynne å teste alt med en gang, så vår første oppgave var å begynne med linting og sjekke syntaksen.
Dag #181: Green Build Master
Linting er et lite første skritt mot Green Build Master. Dette vil ikke ødelegge nesten noe, men det vil tillate deg å feilsøke prosesser og lage grønne bygg i Jenkins. Tanken er å utvikle vaner blant teamet:
Røde tester er dårlige.
Jeg kom for å fikse noe og samtidig gjøre koden litt bedre enn den var før deg.
Dag #193: Fra linting til enhetstester
Etter å ha bygget prosessen med å få koden inn i masteren, kan du begynne prosessen med trinnvise forbedringer - erstatte linting med lanseringsroller, du kan til og med gjøre det uten idempotens. Du må forstå hvordan du bruker roller og hvordan de fungerer.
Dag #211: Fra enhet til integrasjonstester
Når de fleste rollene er dekket med enhetstester og alt er lined, kan du gå videre til å legge til integrasjonstester. De. tester ikke en enkelt kloss i infrastrukturen, men en kombinasjon av dem, for eksempel en full forekomstkonfigurasjon.
Ved å bruke jenkins genererte vi mange stadier som lined roller/playbooks parallelt, deretter enhetstester i containere og til slutt integrasjonstester.
Jenkins + Docker + Ansible = Tester
Sjekk ut repo og generer byggestadier.
Kjør lo-playbook-etapper parallelt.
Kjør lo-rolletrinn parallelt.
Kjør syntakssjekk rollestadier parallelt.
Kjør testrolletrinn parallelt.
Lint rolle.
Sjekk avhengighet av andre roller.
Sjekk syntaks.
Opprett docker-forekomst
Kjør molecule/default/playbook.yml.
Sjekk idempotens.
Kjør integrasjonstester
Finish
Dag #271: Bussfaktor
Til å begynne med ble refaktorisering utført av en liten gruppe på to eller tre personer. De gjennomgikk koden i masteren. Over tid utviklet teamet kunnskap om hvordan man skriver kode og kodegjennomgang bidro til formidling av kunnskap om infrastrukturen og hvordan den fungerer. Høydepunktet her var at anmelderne ble plukket ut én etter én, etter en tidsplan, d.v.s. med en viss grad av sannsynlighet vil du klatre inn i et nytt stykke infrastruktur.
Og det skal være behagelig her. Det er praktisk å gjøre en gjennomgang, se innenfor rammen av hvilken oppgave det ble gjort, og historien til diskusjoner. Vi har integrert jenkins + bitbucket + jira.
Men som sådan er en anmeldelse ikke et universalmiddel; på en eller annen måte kom vi inn i masterkoden, som fikk oss til å flopptester:
Over tid ble det flere tester, byggene gikk tregere, opptil en time i verste fall. På en av retroene var det en setning som "det er bra at det er tester, men de er trege." Som et resultat forlot vi integrasjonstester på virtuelle maskiner og tilpasset dem for Docker for å gjøre det raskere. Vi erstattet også testinfra med en mulig verifikator for å redusere antall verktøy som brukes.
Strengt tatt var det et sett med tiltak:
Bytt til docker.
Fjern rolletesting, som dupliseres på grunn av avhengigheter.
Øk antallet slaver.
Testkjøringsrekkefølge.
Evne til å lo ALLE lokalt med én kommando.
Som et resultat ble også Pipeline på jenkins samlet
Generer byggestadier.
Lo alt parallelt.
Kjør testrolletrinn parallelt.
Bli ferdig.
Erfaringer
Unngå globale variabler
Ansible bruker globale variabler, det er en delvis løsning i skjemaet private_rolle_vars, men dette er ikke et universalmiddel.
La meg gi deg et eksempel. La oss ha role_a и role_b
Det morsomme er at resultatet av lekebøker vil avhenge av ting som ikke alltid er åpenbare, for eksempel rekkefølgen rollene er oppført i. Dessverre er dette Ansibles natur, og det beste som kan gjøres er å bruke en slags avtale, for eksempel innenfor en rolle, bruk kun variabelen som er beskrevet i denne rollen.
Vi ble enige om å bruke variable prefikser; det ville ikke være overflødig å kontrollere at de er definert som vi forventer og for eksempel ikke ble overstyrt av en tom verdi
GOD: Sjekk variabler.
- name: "Verify that required string variables are defined"
assert:
that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
fail_msg: "{{ ahs_var }} needs to be set for the role to work "
success_msg: "Required variables {{ ahs_var }} is defined"
loop_control:
loop_var: ahs_var
with_items:
- ahs_item1
- ahs_item2
- ahs_item3
Unngå hashe-ordbøker, bruk flat struktur
Hvis en rolle forventer en hash/ordbok i en av sine parametere, så hvis vi ønsker å endre en av de underordnede parameterne, må vi overstyre hele hash/ordboken, noe som vil øke konfigurasjonskompleksiteten.
Roller og lekebøker må være idempotente, fordi reduserer konfigurasjonsdrift og frykt for å bryte noe. Men hvis du bruker molekyl, er dette standardoppførselen.
Unngå å bruke kommandoskallmoduler
Å bruke en skallmodul resulterer i et imperativt beskrivelsesparadigme, i stedet for det deklarative, som er kjernen i Ansible.
Test rollene dine via molekyl
Molekyl er en veldig fleksibel ting, la oss se på noen få scenarier.
Molekyl Flere forekomster
В molecule.yml i seksjon platforms du kan beskrive mange verter som du kan distribuere.
I molekyl er det mulig å bruke ansible for å sjekke at instansen er riktig konfigurert, dessuten har dette vært standard siden utgivelse 3. Det er ikke så fleksibelt som testinfra/inspec, men vi kan sjekke at innholdet i filen samsvarer med forventningene våre:
Eller distribuer tjenesten, vent til den blir tilgjengelig og gjør en røyktest:
---
- name: Verify
hosts: solr
tasks:
- command: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
- uri:
url: http://127.0.0.1:8983/solr
method: GET
status_code: 200
register: uri_result
until: uri_result is not failed
retries: 12
delay: 10
- name: Post documents to solr
command: /blah/solr/bin/post -c master /exampledocs/books.csv
Sett kompleks logikk inn i moduler og plugins
Ansible tar til orde for en deklarativ tilnærming, så når du gjør kodeforgrening, datatransformasjon, skallmoduler, blir koden vanskelig å lese. For å bekjempe dette og holde det enkelt å forstå, ville det ikke være overflødig å bekjempe denne kompleksiteten ved å lage dine egne moduler.
Oppsummer tips og triks
Unngå globale variabler.
Prefiks rollevariabler.
Bruk sløyfekontrollvariabel.
Sjekk inngangsvariabler.
Unngå hash-ordbøker, bruk flat struktur.
Lag idempotente lekebøker og roller.
Unngå å bruke kommandoskallmoduler.
Test rollene dine via molekyl.
Sett kompleks logikk inn i moduler og plugins.
Konklusjon
Du kan ikke bare gå og refaktorere infrastrukturen på et prosjekt, selv om du har IaC. Dette er en lang prosess som krever tålmodighet, tid og kunnskap.
UPD1 2020.05.01 20:30 — For primær profilering av playbooks kan du bruke callback_whitelist = profile_tasks å forstå hva som fungerer i lang tid. Så går vi gjennom Ansible akselerasjonsklassikere. Du kan også prøve mitogen UPD2 2020.05.03 16:34 - Angielski versjon