Infrastructura ca cod: modul în care Am renovat procesul nostru de dezvoltare / lansare pentru a accepta scara echipei noastre

(11 decembrie 2020)

În acest articol, vă prezentăm modul în care am gestionat procesul nostru de implementare continuă în trecut, ceea ce ne-a determinat să schimbăm ceea ce avem, și ce eforturi am făcut pentru ca procesul să fie cât mai simplu / eficient posibil.

Articolul poate da un gust inițial, dar, în esență, procesul de lansare afectează toate echipele și modul în care acestea funcționează singure. sau colaborăm cu alte echipe, vom arăta cum se schimbă rolurile doar prin schimbarea procesului.

Despre noi

La Halan vă oferim soluții logistice la cerere și la cerere ( rate, livrare, plăți online, comerț electronic) pentru populația insuficient deservită de tehnologiile existente în transport și alte servicii, puteți consulta p aici ( android / iOS )

Oferirea vechiului proces se datorează, bine și rău

Vom începe prin modul în care ne-am gestionat procesul în trecut și modul în care acest lucru ne-a afectat fie pozitiv, fie negativ.

Pentru echipa mea, avem aproape tot ce se desfășoară în AWS cu GitHub ca sistem de control al versiunilor noastre, așa că trebuie să găsim o modalitate de a livra caracteristici de la depozitele noastre GitHub la serviciile AWS.

Implementări de control al versiunii

Noi m-am bazat pe conductă cod AWS , am setat declanșatoare pentru a porni o conductă de implementare ori de câte ori un nou commit este fuzionat într-una dintre ramurile principale reprezentând etapele cunoscute: dev , prod și organizare .

prezentare generală a modului în care sunt declanșate implementările

Acest flux înseamnă că orice caracteristică din ramura principală este la producție, care face sigur că fuzionarea pentru a stăpâni un subiect tabu de discutat și nu toată lumea a avut permisiunea pentru a vă îmbina PR-ul pe master.

Același lucru a fost pentru alte ramuri, dar asta nu a fost Într-adevăr, este o problemă, întrucât programele de difuzare și de expediere nu sunt chiar atât de înfricoșătoare.

QC-ul nostru a început să testeze și să verifice caracteristicile atunci când acestea sunt îmbinate în repaus, ceea ce înseamnă că testează mai întâi pe rep de punere în scenă, apoi dacă sunt verificate , caracteristica va fi îmbinată cu ramura master . asta pare să funcționeze bine, dar să ne uităm la dezavantajele unui astfel de proces.

Acest lucru ne-a permis să testăm și să implementăm mai multe caracteristici în același timp pe fiecare etapă (dev, etapizare), ceea ce este bun și rău la în același timp, deoarece:

  • Asta înseamnă că dezvoltatorii nu trebuie să aștepte unii pe alții pentru a obține controlul asupra mediului de dezvoltare / stagiere.
  • Dar înseamnă că funcțiile de pe stadiul dev ar putea în mod greșit să facă ca fiecare să nu funcționeze sau funcționează (fals pozitiv) și ambele cazuri sunt foarte rele și ar putea face ca codul să intre în producție în timp ce nu funcționează cu adevărat.

Ramuri divergente, rebasare inutilă

După cum probabil ați observat deja, am spus că, pentru a putea fi implementat pe dev env, trebuie să vă îmbinați codul pe ramura dev. Din păcate, acea parte a deranjat rapid cronologia filialei noastre, deoarece:

  • Nu toate caracteristicile testate pe dev intră în producție, așa că am avut ca niște comisii fantomă stabilite în ramura noastră dev unitar .
  • Un laborator de experimentare fără îndoială, este posibil ca oamenii să descopere că au făcut ceva greșit după un timp și să decidă să renunțe la codul / comitetele și să înceapă unul nou, dar asta ne lasă totuși cu vechile lor comisii. fuzionat pe ramura dev.

Acest tip de comportament a produs ceea ce numim divergență între ramuri, pentru a fuziona o caracteristică ramură care are ca bază bază în dev, trebuie să rezolvați conflicte ! ceea ce este ciudat de ciudat, vă confruntând literalmente cu fantomele și rezolvând lucruri care nu vor mai fi niciodată la producție , ceea ce vă oferă cu siguranță două opțiuni slabe:

  • Construiește o ramură nouă pentru caracteristica ta bifurcată din ramura de caracteristică originală și rezolvă conflictele de pe aceasta, apoi, la finalizarea testării, fuzionează ramura originală în master.
  • Rezolvați conflictele de pe filiala dvs., apoi cireșul vă alege angajamentele într-o filială nouă atunci când fuzionați în master.

Odată ce mai mulți dezvoltatori se alătură echipei noastre, lucrurile vor începe să devină mai urâte iar divergența va lua cu siguranță o creștere.

Reorganizarea procesului de construire / implementare

Primul lucru pe care l-am avut în vedere este cum să scăpăm de acele ramuri divergente, avem nevoie de o nouă metodă să livreze în siguranță caracteristici la producție fără probleme și să controlați câte funcții sunt implementate în producție fără a implica controlul sursei cu afacerea de implementare.

O mică recenzie pe AWS

Mai întâi trebuie să identificăm principalele elemente care vor juca un rol cu ​​noi în acest proces:

  • Github : control sursă având repozite pentru fiecare micro-serviciu acolo.
  • Amazon ECR : un registru de imagini Docker care este împărțit în „repo”, fiecare repo reprezintă și un mic-serviciu și conține imaginile care au fost împinse pentru serviciul X și care pot fi utilizate sau implementate direct în acest serviciu pentru a-l face să funcționeze.
  • Amazon ECS / EC2 / EKS : aici trăiesc micro-serviciile noastre, împreună cu mediile lor, ECS este împărțit în clustere, fiecare cluster deține un număr de servicii, fiecare are o definiție a sarcinii care conține informații precum variabile de mediu , calculați specificațiile, rețeaua etc.

Deci, trebuie să găsim o modalitate de a le lega împreună pentru a ne fi mai ușor ca echipă de dezvoltatori să livrăm caracteristici și pentru QC să le controlăm și să le verificăm caracteristici.

Ne-am gândit că putem defini un serviciu intermediar, un serviciu care este responsabil pentru implementarea altor servicii Aveam două comenzi principale pe care doream să le gestionăm acest serviciu:

  • Comandă Build: noi dorim să putem construi o imagine și să o împingem la ECR din orice ramură / commit pe care o dorim de la o anumită repo GitHub la o anumită repo ECR.
  • Deploy Command: vrem să putem implementa o anumită imagine dintr-o repo pe ECR către toate clusterele care dețin serviciul X.

Să luăm fiecare dintre aceste comenzi la microscop și vedem ce implică fiecare dintre acestea, începem cu Build Comandă:

  • Mai întâi de toate, trebuie să clonăm repo la comiterea / ramificația specificată.
  • Construiți o imagine de andocare folosind fișierul Docker din acea repo.
  • Apăsați imagine construită în ECO repo cu o nouă etichetă, dacă este necesar sau mai recent.

În timp ce toți acești pași sunt cu siguranță doab le în noul nostru serviciu de implementare, dar am constatat că este greoi, deoarece crearea docker imaginile consumă o mulțime de resurse și asta va limita noul nostru serviciu la câteva simultane implementări sau o facem atât de gigantică în resurse.

Ne-am gândit că, în loc să facem toate aceste lucrări pe serviciu, am putea începe un nou flux de lucru pe Github pe acea repo și transmiteți-o la toate detalii despre sarcină, cum ar fi ce ramură să plătiți și ce repo ECR să împingă, când se termină în sfârșit, va semnaliza utilizatorul înapoi utilizând un web-hook . Desigur, există și alte soluții, cum ar fi Jenkins, pentru o securitate mai bună, pentru a vă asigura că codul dvs. se bazează pe mașinile pe care le gestionați.

Acest lucru a schimbat fluxul de lucru menționat mai sus, acum merge după cum urmează:

  • Primiți detalii de construcție de la utilizator.
  • Declanșați o acțiune Github repo specificat.
  • Acțiunile Github vor învârti o nouă mașină care ne va notifica înapoi cu starea de construire atunci când gata, va eticheta și commit-ul cu numărul cardului Jira la care lucrați.

A doua comandă este comanda Depoly , care este mult mai simplă decât comanda build, aici nu trebuie decât să:

  • Primiți detalii despre implementare de la utilizator.
  • Porniți o nouă sarcină de implementare pe fiecare cluster care conține serviciul și furnizează adresa URL a imaginii în ECR.

flux de lucru de implementare

Asta este într-adevăr pentru implementare! doar o treabă de facilitare între două produse AWS, să comparăm acest flux de lucru cu ceea ce aveam înainte și să vedem cum s-a schimbat strategia noastră de lansare.

Utilizarea noului proces pentru a implementa codul dvs. în oricare dintre etape (prod, dev, etapizare) nu necesită niciun fel de divizii fuzionează , codul este complet independent de implementare , am putea avea 20 caracteristici gata pe ramura principală și alege doar să să implementeze 10 dintre ele.

Dar acest lucru implică și faptul că putem avea doar o caracteristică fiind testat pe ramura dev, cu excepția cazului în care doi dev au fost de acord să rebase unul pe celălalt.

Istoricul implementării și etichetarea

Acest lucru ne-a oferit și un rollback mai bun strategie împotriva problemelor de producție, acum avem o ramură principală etichetată pentru fiecare caracteristică / sarcină am avut, ori de câte ori ne confruntăm cu o problemă de producție și dorim să retrogradăm o caracteristică, putem naviga cu ușurință înapoi la locul în care a început această caracteristică și să revenim la comitere înainte de ea, dacă este posibil.

De asemenea, acest lucru ne-a permis să îmbinăm toate caracteristicile de lucru de pe filiala master, chiar dacă acestea nu vor fi implementate, le putem avea în continuare pe master pregătite pentru următorul lot de caracteristici care vor fi în producție atunci când este necesar, ceea ce ne va ajuta cu siguranță echipa se concentrează pe livrarea sarcinilor fără să vă faceți griji cu privire la momentul în care sarcina va fi îmbinată cu masterul care urmează să fie implementat, aici fuzionăm mai întâi, apoi ne facem griji cu privire la implementări.

Pașii următori

În prezent lucrăm la automat procesul nostru mai bine, inclusiv variabilele de mediu și specificațiile mașinii, toate vor fi disponibile ca cod, ori de câte ori schimbăm specificațiile, care vor reflecta automat ect pe mașinile noastre pe AWS în mediu respectiv , nu este nevoie să codificați manual aceste valori de fiecare dată pe AWS.

Cu aceasta, vom avea un control mai bun și vizibilitate la toate configurațiile serviciilor noastre, totul în infrastructura noastră va fi în cod și la un clic distanță pentru actualizare! De asemenea, ceea ce face ca schimbarea infrastructurii noastre să fie independentă de furnizorul de servicii, am putea trece de la AWS la cloud Google, de exemplu, și trebuie doar să schimbăm comenzile utilizate de serviciul de implementare pentru a implementa infrastructura noastră pe noul furnizor de servicii.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *