Ce am învățat din testarea a 200 de linii de cod de infrastructură

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Abordarea IaC (Infrastructure as Code) constă nu numai din codul care este stocat în depozit, ci și din persoanele și procesele care înconjoară acest cod. Este posibil să se refolosească abordări de la dezvoltarea software-ului la managementul și descrierea infrastructurii? Ar fi o idee bună să țineți cont de această idee în timp ce citiți articolul.

Versiunea Inglese

Aceasta este o transcriere a mea spectacole pe DevopsConf 2019-05-28.

Slide-uri și videoclipuri

Infrastructura ca istorie bash

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Să presupunem că vii la un nou proiect și îți spun: „avem Infrastructura ca Cod". În realitate se dovedește Infrastructura ca istorie bash sau de exemplu Documentație ca istoric bash. Aceasta este o situație foarte reală, de exemplu, un caz similar a fost descris de Denis Lysenko într-un discurs Cum să înlocuiți întreaga infrastructură și să începeți să dormiți liniștit, a povestit cum au obținut o infrastructură coerentă pentru proiect din istoria bash.

Cu ceva dorință, putem spune asta Infrastructura ca istorie bash acesta este ca codul:

  1. reproductibilitatea: Puteți lua istoricul bash, rulați comenzile de acolo și, apropo, puteți obține o configurație de lucru ca rezultat.
  2. versiunea: știți cine a intrat și ce au făcut, din nou, nu este un fapt că acest lucru vă va conduce la o configurație de lucru la ieșire.
  3. poveste: povestea cine a făcut ce. numai că nu îl vei putea folosi dacă pierzi serverul.

Ce să fac?

Infrastructura ca Cod

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Chiar și un caz atât de ciudat ca Infrastructura ca istorie bash îl poți trage de urechi Infrastructura ca Cod, dar când vrem să facem ceva mai complicat decât vechiul server LAMP bun, vom ajunge la concluzia că acest cod trebuie cumva modificat, schimbat, îmbunătățit. În continuare, am dori să luăm în considerare paralelele dintre Infrastructura ca Cod și dezvoltare software.

USCAT.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Pe un proiect de dezvoltare a unui sistem de stocare, a existat o sarcină secundară configurați periodic SDS: lansăm o nouă versiune - trebuie să fie lansată pentru testare ulterioară. Sarcina este extrem de simplă:

  • conectați-vă aici prin ssh și executați comanda.
  • copiați fișierul acolo.
  • corectați configurația aici.
  • începe serviciul acolo
  • ...
  • PROFIT!

Pentru logica descrisă, bash este mai mult decât suficient, mai ales în fazele incipiente ale proiectului, când acesta abia începe. Acest nu e rău că folosești bash, dar de-a lungul timpului există solicitări de a implementa ceva similar, dar ușor diferit. Primul lucru care îmi vine în minte este copy-paste. Și acum avem deja două scripturi foarte asemănătoare care fac aproape același lucru. De-a lungul timpului, numărul de scripturi a crescut și ne-am confruntat cu faptul că există o anumită logică de business pentru implementarea unei instalări care trebuie sincronizată între diferite scripturi, acest lucru este destul de complicat.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Se pare că există o astfel de practică precum D.R.Y. (Nu te repeta). Ideea este de a reutiliza codul existent. Sună simplu, dar nu am ajuns la asta imediat. În cazul nostru, a fost o idee banală: să separăm configurațiile de scripturi. Acestea. logica de afaceri a modului în care instalarea este implementată separat, configurațiile separat.

SOLID. pentru CFM

Ce am învățat din testarea a 200 de linii de cod de infrastructură

De-a lungul timpului proiectul a crescut și continuare firească a fost apariția lui Ansible. Motivul principal al apariției sale este că există expertiză în echipă și că bash nu este conceput pentru o logică complexă. Ansible a început să conțină și o logică complexă. Pentru a preveni transformarea logicii complexe în haos, există principii de organizare a codului în dezvoltarea de software SOLID. De asemenea, de exemplu, Grigory Petrov în raportul „De ce are nevoie un specialist IT de un brand personal” a pus întrebarea că o persoană este concepută în așa fel încât să îi fie mai ușor să opereze cu unele entități sociale, în dezvoltarea de software acestea sunt obiecte. Dacă combinăm aceste două idei și continuăm să le dezvoltăm, vom observa că putem folosi și noi SOLID. pentru a facilita menținerea și modificarea acestei logici în viitor.

Principiul responsabilității unice

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Fiecare clasă îndeplinește o singură sarcină.

Nu este nevoie să amestecați codul și să faceți monștri de spaghete divine monolitice. Infrastructura ar trebui să fie compusă din cărămizi simple. Se pare că, dacă împărțiți manualul Ansible în bucăți mici, citiți roluri Ansible, atunci acestea sunt mai ușor de întreținut.

Principiul Deschis Închis

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Principiul deschis/închis.

  • Deschis la extensie: înseamnă că comportamentul unei entități poate fi extins prin crearea de noi tipuri de entități.
  • Închis la modificare: ca urmare a extinderii comportamentului unei entități, nu trebuie făcute modificări codului care utilizează acele entități.

Inițial, am implementat infrastructura de testare pe mașini virtuale, dar datorită faptului că logica de afaceri a implementării a fost separată de implementare, am adăugat lansarea la baremetall fără probleme.

Principiul substituției Liskov

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Principiul de substituție al Barbara Liskov. obiectele dintr-un program trebuie să fie înlocuibile cu instanțe ale subtipurilor lor fără a modifica execuția corectă a programului

Dacă te uiți la asta mai larg, nu este o caracteristică a unui anumit proiect care poate fi aplicată acolo SOLID., este vorba, în general, despre CFM, de exemplu, pe un alt proiect este necesară implementarea unei aplicații Java în cutie peste diverse Java, servere de aplicații, baze de date, OS etc. Folosind acest exemplu, voi lua în considerare alte principii SOLID.

În cazul nostru, există un acord în cadrul echipei de infrastructură că, dacă am instalat rolul imbjava sau oraclejava, atunci avem un executabil binar java. Acest lucru este necesar deoarece Rolurile din amonte depind de acest comportament; se așteaptă la Java. În același timp, acest lucru ne permite să înlocuim o implementare/versiune java cu alta fără a schimba logica de implementare a aplicației.

Problema aici constă în faptul că este imposibil de implementat acest lucru în Ansible, în urma căruia apar unele acorduri în cadrul echipei.

Principiul segregării interfeței

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Principiul de separare a interfeței: „Multe interfețe specifice clientului sunt mai bune decât o interfață de uz general.

Inițial, am încercat să punem toată variabilitatea implementării aplicației într-un singur manual Ansible, dar a fost dificil de susținut, iar abordarea când avem o interfață externă specificată (clientul se așteaptă la portul 443), apoi o infrastructură poate fi asamblată de la individual cărămizi pentru o implementare specifică.

Principiul inversiunii dependenței

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Principiul inversării dependenței. Modulele de la nivelurile superioare nu ar trebui să depindă de modulele de la nivelurile inferioare. Ambele tipuri de module trebuie să depindă de abstracții. Abstracțiile nu ar trebui să depindă de detalii. Detaliile trebuie să depindă de abstracții.

Aici exemplul se va baza pe un antipattern.

  1. Unul dintre clienți avea un cloud privat.
  2. Am comandat mașini virtuale în cloud.
  3. Dar, din cauza naturii cloud-ului, implementarea aplicației a fost legată de hipervizorul activat VM.

Acestea. Logica de implementare a aplicațiilor la nivel înalt a fost transmisă cu dependențe către nivelurile inferioare ale hypervisorului, iar acest lucru a însemnat probleme la reutilizarea acestei logici. Nu face acest lucru.

Interacțiune

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Infrastructura ca cod nu este doar despre cod, ci și despre relația dintre cod și oameni, despre interacțiunile dintre dezvoltatorii de infrastructură.

Factorul de autobuz

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Să presupunem că îl aveți pe Vasya în proiect. Vasya știe totul despre infrastructura ta, ce se va întâmpla dacă Vasya va dispărea brusc? Aceasta este o situație foarte reală, pentru că ar putea fi lovit de un autobuz. Uneori se întâmplă. Dacă se întâmplă acest lucru și cunoștințele despre cod, structura acestuia, cum funcționează, aparițiile și parolele nu sunt distribuite în echipă, atunci este posibil să întâmpinați o serie de situații neplăcute. Pentru a minimiza aceste riscuri și pentru a distribui cunoștințele în cadrul echipei, puteți utiliza diverse abordări

Pereche Devopsing

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Nu este ca ca o gluma, că administratorii au băut bere, au schimbat parole și un analog al programării perechilor. Acestea. doi ingineri se așează la un computer, o tastatură și încep să vă configureze infrastructura împreună: configurați un server, scrieți un rol Ansible etc. Sună frumos, dar nu a funcționat pentru noi. Dar cazuri speciale ale acestei practici au funcționat. Vine un nou angajat, mentorul său preia o sarcină reală împreună cu el, lucrează și transferă cunoștințe.

Un alt caz special este un apel pentru incident. În timpul unei probleme, se adună un grup de cei de serviciu și cei implicați, este desemnat un lider, care își împărtășește ecranul și își dă glasul gândurilor. Alți participanți urmăresc gândurile liderului, spionează trucurile din consolă, verifică dacă nu au ratat niciun rând din jurnal și învață lucruri noi despre sistem. Această abordare a funcționat de cele mai multe ori.

Revizuirea codului

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Din punct de vedere subiectiv, a fost mai eficient să se disemineze cunoștințele despre infrastructură și modul în care funcționează folosind revizuirea codului:

  • Infrastructura este descrisă prin cod în depozit.
  • Schimbările apar într-o ramură separată.
  • În timpul unei solicitări de fuziune, puteți vedea delta modificărilor în infrastructură.

Punctul culminant aici a fost faptul că recenzenții au fost selectați unul câte unul, conform unui program, de exemplu. cu un anumit grad de probabilitate vei urca într-o nouă piesă de infrastructură.

Stil cod

Ce am învățat din testarea a 200 de linii de cod de infrastructură

De-a lungul timpului, în timpul recenziilor au început să apară certuri, pentru că... recenzenții au avut propriul stil și rotația recenzenților le-a stivuit cu diferite stiluri: 2 spații sau 4, camelCase sau snake_case. Nu a fost posibil să implementăm acest lucru imediat.

  • Prima idee a fost de a recomanda utilizarea linter, la urma urmei, toată lumea este inginer, toată lumea este inteligentă. Dar diferite editori, OS, nu sunt convenabile
  • Aceasta a evoluat într-un bot care a scris la slack pentru fiecare comitere problematică și a atașat ieșirea linter. Dar în cele mai multe cazuri au fost lucruri mai importante de făcut și codul a rămas neremediat.

Green Build Master

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Timpul trece și am ajuns la concluzia că comitetele care nu trec anumite teste nu pot fi admise în master. Voila! Am inventat Green Build Master, care a fost practicat de mult timp în dezvoltarea de software:

  • Dezvoltarea este în curs într-o ramură separată.
  • Testele rulează pe acest thread.
  • Dacă testele eșuează, codul nu va ajunge în master.

Luarea acestei decizii a fost foarte dureroasă, pentru că... a provocat multe controverse, dar a meritat, pentru că... Recenziile au început să primească cereri de fuziuni fără diferențe de stil, iar în timp numărul zonelor cu probleme a început să scadă.

Testarea IaC

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Pe lângă verificarea stilului, puteți folosi și alte lucruri, de exemplu, pentru a verifica dacă infrastructura dvs. se poate implementa efectiv. Sau verificați că modificările în infrastructură nu vor duce la pierderi de bani. De ce ar putea fi nevoie de acest lucru? Întrebarea este complexă și filozofică, este mai bine să răspundem cu o poveste că a existat cumva un auto-scaler pe Powershell care nu a verificat condițiile la limită => au fost create mai multe VM decât era necesar => clientul a cheltuit mai mulți bani decât era planificat. Acest lucru nu este foarte plăcut, dar ar fi foarte posibil să detectați această eroare în etapele anterioare.

S-ar putea întreba, de ce să facem infrastructura complexă și mai complexă? Testele pentru infrastructură, la fel ca și pentru cod, nu sunt despre simplificare, ci despre cum ar trebui să funcționeze infrastructura dvs.

Piramida de testare IaC

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Testarea IaC: Analiză Statică

Dacă implementați întreaga infrastructură simultan și verificați dacă funcționează, este posibil să descoperiți că durează mult și necesită mult timp. Prin urmare, baza trebuie să fie ceva care funcționează rapid, există o mulțime de ea și acoperă o mulțime de locuri primitive.

Bash este complicat

Să ne uităm la un exemplu banal. selectați toate fișierele din directorul curent și copiați în altă locație. Primul lucru care îmi vine în minte:

for i in * ; do 
    cp $i /some/path/$i.bak
done

Ce se întâmplă dacă există un spațiu în numele fișierului? Ei bine, bine, suntem deștepți, știm să folosim ghilimele:

for i in * ; do cp "$i" "/some/path/$i.bak" ; done

Bine făcut? Nu! Ce se întâmplă dacă nu există nimic în director, de exemplu globbing nu va funcționa.

find . -type f -exec mv -v {} dst/{}.bak ;

bine făcut acum? Nu... Am uitat ce poate fi în numele fișierului n.

touch x
mv x  "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir

Instrumente de analiză statică

Problema de la pasul anterior ar putea fi prinsă când am uitat ghilimele, pentru asta există multe remedii în natură Shellcheck, în general, există o mulțime de ele și, cel mai probabil, puteți găsi un linter pentru stiva dvs. sub IDE.

Limbă
Instrument

pocni
Shellcheck

Rubin
RuboCop

piton
pilint

ansible
Ansible Lint

Testarea IaC: teste unitare

Ce am învățat din testarea a 200 de linii de cod de infrastructură

După cum am văzut din exemplul anterior, linters nu sunt omnipotenți și nu pot indica toate zonele cu probleme. În plus, prin analogie cu testarea în dezvoltarea de software, putem aminti testele unitare. Ceea ce îmi vine imediat în minte este shunit, junit, rspec, pytest. Dar ce să faci cu ansible, bucătar, saltstack și altele asemenea?

La început am vorbit despre SOLID. și că infrastructura noastră ar trebui să fie formată din cărămizi mici. Le-a venit vremea.

  1. Infrastructura este împărțită în cărămizi mici, de exemplu, roluri Ansible.
  2. Este implementat un fel de mediu, fie el docker sau VM.
  3. Ne aplicăm rolul Ansible acestui mediu de testare.
  4. Verificăm dacă totul a funcționat așa cum ne-am așteptat (facem teste).
  5. Decidem ok sau nu ok.

Testarea IaC: instrumente de testare unitară

Întrebare, ce sunt testele pentru CFM? Puteți rula pur și simplu scriptul sau puteți utiliza soluții gata făcute pentru aceasta:

CFM
Instrument

ansiblu
Testinfra

bucătar-șef
Inspect

bucătar-șef
Serverspec

stiva de sare
Goss

Exemplu pentru testinfra, verificând că utilizatorii test1, test2 există și sunt într-un grup sshusers:

def test_default_users(host):
    users = ['test1', 'test2' ]
    for login in users:
        assert host.user(login).exists
        assert 'sshusers' in host.user(login).groups

Ce sa aleg? Întrebarea este complexă și ambiguă, iată un exemplu de modificări ale proiectelor pe github pentru 2018-2019:

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Cadre de testare IaC

Apare întrebarea: cum să le punem totul împreună și să-l lansăm? Poate sa ia-o și fă-o singur dacă există un număr suficient de ingineri. Sau puteți lua soluții gata făcute, deși nu sunt foarte multe:

CFM
Instrument

ansiblu
Moleculă

bucătar-șef
Test Bucătărie

Terraform
Terratest

Exemplu de modificări ale proiectelor pe github pentru 2018-2019:

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Moleculă vs. Test Kitchen

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Initial noi am încercat să folosesc testkitchen:

  1. Creați o VM în paralel.
  2. Aplicați roluri Ansible.
  3. Efectuați inspecția.

Pentru 25-35 de roluri a funcționat 40-70 de minute, ceea ce a fost lung.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Următorul pas a fost trecerea la jenkins/docker/ansible/molecule. Idiologic totul este la fel

  1. Lint playbooks.
  2. Aliniați rolurile.
  3. Lansați containerul
  4. Aplicați roluri Ansible.
  5. Rulați testinfra.
  6. Verifica idempotenta.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Litting pentru 40 de roluri și teste pentru o duzină au început să dureze aproximativ 15 minute.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Ce să alegeți depinde de mulți factori, cum ar fi stiva utilizată, expertiza în echipă etc. aici fiecare decide singur cum să închidă întrebarea Testarea unitară

Testare IaC: Teste de integrare

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Următorul pas în piramida de testare a infrastructurii va fi testele de integrare. Sunt similare cu testele unitare:

  1. Infrastructura este împărțită în cărămizi mici, de exemplu roluri Ansible.
  2. Este implementat un fel de mediu, fie el docker sau VM.
  3. Pentru acest mediu de testare se aplică set de Roluri ansible.
  4. Verificăm dacă totul a funcționat așa cum ne-am așteptat (facem teste).
  5. Decidem ok sau nu ok.

În linii mari, nu verificăm performanța unui element individual al sistemului ca în testele unitare, verificăm modul în care serverul este configurat în ansamblu.

Testare IaC: teste de la capăt la capăt

Ce am învățat din testarea a 200 de linii de cod de infrastructură

În vârful piramidei suntem întâmpinați de teste End to End. Acestea. Nu verificăm performanța unui server separat, a unui script separat sau a unei cărămizi separate a infrastructurii noastre. Verificăm dacă multe servere sunt conectate împreună, infrastructura noastră funcționează așa cum ne așteptăm. Din păcate, nu am văzut niciodată soluții gata făcute în cutie, probabil pentru că... Infrastructura este adesea unică și dificil de șablonat și de a crea un cadru pentru testare. Drept urmare, fiecare își creează propriile soluții. Există o cerere, dar nu există niciun răspuns. Prin urmare, vă voi spune ce există pentru a-i împinge pe alții să sune gânduri sau să mă frece cu nasul în faptul că totul a fost inventat cu mult timp înaintea noastră.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Un proiect cu o istorie bogată. Este folosit în organizații mari și probabil că fiecare dintre voi s-a intersectat indirect cu el. Aplicația acceptă multe baze de date, integrări etc. A ști cum ar putea arăta infrastructura înseamnă o mulțime de fișiere docker-compose și a ști ce teste să ruleze în ce mediu este Jenkins.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Această schemă a funcționat destul de mult timp, până în cadrul cercetare nu am încercat să transferăm acest lucru în Openshift. Containerele rămân aceleași, dar mediul de lansare s-a schimbat (bună ziua D.R.Y. din nou).

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Ideea cercetării a mers mai departe și în schimbul deschis au găsit un astfel de lucru precum APB (Ansible Playbook Bundle), care vă permite să acumulați cunoștințe despre cum să implementați infrastructura într-un container. Acestea. există un punct de cunoștințe repetabil și testabil cu privire la modul de implementare a infrastructurii.

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Toate acestea au sunat bine până când ne-am lovit de o infrastructură eterogenă: aveam nevoie de Windows pentru teste. Ca rezultat, cunoștințele despre ce, unde, cum să implementați și să testați se află în jenkins.

Concluzie

Ce am învățat din testarea a 200 de linii de cod de infrastructură

Infrastructura așa cum este codul

  • Cod în depozit.
  • Interacțiune umană.
  • Testarea infrastructurii.

Link-uri

Sursa: www.habr.com

Adauga un comentariu