Infrastruktur som kode: Hvordan vi Fornyet vores udviklings- / frigivelsesproces for at omfatte vores teamskala

(11. dec. 2020)

I denne artikel viser vi, hvordan vi tidligere har håndteret vores kontinuerlige implementeringsproces, hvad der fik os til at ændre det, vi har, og hvilke bestræbelser vi har gjort for at gøre processen så enkel / effektiv som muligt.

Artiklen kan give en indledende devops-smag, men i det væsentlige påvirker frigivelsesprocessen alle hold og hvordan de fungerer alene eller samarbejder med andre teams, vil vi vise, hvordan roller skiftes bare ved at ændre processen.

Om os

Vi i Halan hjælper med at tilbyde ridehail og on-demand logistikløsninger ( afdrag, levering, betaling online, e-handel) for den underbetjente befolkning af de eksisterende teknologier inden for transport og andre tjenester, kan du tjekke vores ap p her ( android / iOS )

Giv den gamle proces det skyldes, det gode og det dårlige

Vi starter med, hvordan vi håndterede vores proces tidligere, og hvordan det påvirkede os enten positivt eller negativt.

For mit team har vi næsten alt implementeret over AWS med GitHub som vores versionskontrolsystem, så vi er nødt til at finde ud af en måde at sende funktioner fra vores GitHub repos til AWS-tjenester.

Versionskontrollerende implementeringer

Vi stole på AWS-kodepipeline , vi indstiller udløsere til at starte en implementeringsrørledning hver gang en ny forpligtelse flettes til en af ​​hovedgrene, der repræsenterer de kendte stadier: dev , prod og iscenesættelse miljøer.

oversigt over, hvordan implementeringer udløses

Dette flow betyder at enhver funktion på mastergrenen er på produktion, der helt sikkert gør fletning for at mestre et tabuemne at diskutere og ikke alle havde at tilladelse til at fusionere din PR til master.

Samme ting var for andre grene, men det var ikke t virkelig et problem, da dev og iscenesættelse envs ikke rigtig er så skræmmende.

Vores QC startede med at teste og verificere funktioner, når de flettes på iscenesættelsen, hvilket betyder, at de først tester på iscenesættelse env derefter, hvis de er bekræftet , bliver funktionen flettet i master -grenen. det ser ud til at fungere fint, men lad os se på ulemperne ved en sådan proces.

Dette tillod os at teste og implementere flere funktioner på samme tid på hvert trin (dev, iscenesættelse), hvilket er godt og dårligt til samme tid fordi:

  • Det betyder, at udviklere ikke behøver at vente på hinanden for at få kontrol over dev / staging-miljøet.
  • Men det betyder, at funktioner på dev-fase kunne fejlagtigt forårsage hinanden til enten ikke fungerer eller arbejde (falsk positiv), og begge disse sager er virkelig dårlige og kan være få koden til at gå i produktion, mens den ikke rigtig fungerer.

Divergerende grene, unødvendig omlægning

Som du måske allerede har bemærket, sagde vi det for at implementere på dev env, skal du flette din kode på dev-grenen. Nå, den del ødelagde desværre hurtigt tidslinjen for vores gren som:

  • Ikke alle funktioner, der er blevet testet på dev, går i produktion, så vi havde ligesom spøgelsesforpligtelser, der lå i vores samlede dev-gren .
  • Et eksperimentelaboratorium uden tvivl, folk kan opdage, at de har gjort noget forkert efter et stykke tid og beslutter at droppe deres kode / forpligtelser og starte en ny, men det efterlader os stadig med deres gamle forpligtelser fusioneret på dev-grenen.

Denne form for adfærd producerede det, vi kalder divergens mellem grene, for at fusionere en -funktion gren, der har master som sin base til dev, skal du løse konflikter ! hvilket er akavet underligt, du bogstaveligt talt er i konflikt med spøgelser og løser ting, der aldrig kommer til at være på produktion , hvilket helt sikkert giver dig to dårlige muligheder:

  • Byg en ny gren til din funktion forked fra din oprindelige funktionsgren og løs konflikter på den, og flet den oprindelige filial til master, når du er færdig med at teste.
  • Løs konflikter i din gren, og vælg derefter dine forpligtelser i en ny gren, når de flettes til master.

Når flere udviklere tilslutter sig vores team, vil tingene blive mere grimme og divergens vil helt sikkert tage en stigning op.

Fornyelse af build / deploy-processen

Den første ting, vi havde i tankerne, er, hvordan vi kan slippe af med de divergerende grene, vi har brug for en ny metode til sikkert at levere funktioner til produktion problemfrit og kontrollere, hvor mange funktioner der implementeres på produktion uden at involvere kildekontrol med implementeringsvirksomhed.

En lille gennemgang af AWS

Først skal vi identificere de vigtigste elementer, der vil spille en rolle med os i processen:

  • Github : kilde kontrol har repos for hver mikrotjeneste derude.
  • Amazon ECR : en Docker-billedregistrering, der er opdelt i repos, repræsenterer hver repo også en mikrotjeneste og indeholder de billeder, der er skubbet til tjeneste X og kan bruges eller implementeres i denne tjeneste direkte for at få den til at fungere.
  • Amazon ECS / EC2 / EKS : det er her, vores mikrotjenester bor sammen med deres miljøer, ECS er opdelt i klynger, hver klynge har et antal tjenester, hver har opgavedefinition, der indeholder information som miljøvariabler , beregne specifikationer, netværk osv.

Så vi er nødt til at finde en måde at binde dem sammen for at gøre det lettere for os som dev-team at levere funktioner og for QC at kontrollere og verificere dem funktioner.

Vi regnede med, at vi kunne definere en mellemmandstjeneste, en -tjeneste , der er ansvarlig for implementering af andre tjenester. Vi havde to hovedkommandoer, som vi ville have denne tjeneste til at håndtere:

  • Byg kommando: we ønsker at være i stand til at opbygge et billede og skubbe det til ECR fra enhver gren / forpligtelse, vi ønsker fra en bestemt GitHub-repo til en bestemt ECR-repo.
  • Implementér kommando: vi vil være i stand til at distribuere et bestemt billede fra en repo på ECR til alle klynger, der holder tjeneste X.

Lad os tage hver af disse kommandoer under mikroskopet og se hvad hver af disse involverer, vi begynder med Byg Kommando:

  • Først og fremmest er vi nødt til at klone repoen ved den angivne forpligtelse / gren.
  • Byg et dockerbillede ved hjælp af Dockerfile i den repo.
  • Skub bygget billede til ECR repo med et nyt tag, hvis det er nødvendigt eller senest.

Selvom alle disse trin helt sikkert er doab le i vores nye implementeringstjeneste, men vi fandt ud af, at det er besværligt, da bygning af docker billeder bruger en masse ressourcer og det vil begrænse vores nye tjeneste til et par samtidige implementeringer eller gør det så gigantisk i ressourcer.

Vi regnede med, at vi kunne i stedet for at udføre alt dette arbejde på selve tjenesten, kunne vi starte en ny workflow Github på denne repo og videregive til det hele opgaveoplysninger såsom hvilken gren, der skal kasseres, og hvilken ECR repo, der skal skubbes til, når den endelig er færdig, vil den signalere brugeren tilbage ved hjælp af en web-hook . Selvfølgelig er der andre løsninger til det som Jenkins for bedre sikkerhed for at sikre, at din kode bygger på maskiner, du administrerer.

Det ændrede den arbejdsgang, vi nævnte ovenfor, den går nu som følger:

  • Modtag build-detaljer fra brugeren.
  • Udløs en Github handling på handlingen specificeret repo.
  • Github-handlinger drejer en ny maskine , der giver os besked tilbage med build-status, når færdig, det vil også tagge forpligtelsen med det Jira-kortnummer , du arbejder på.

Anden kommando er Depoly kommandoen, hvilket er langt enklere end build-kommandoen, vi skal kun her:

  • Modtag detaljer om implementering fra brugeren.
  • Start en ny implementeringsopgave på hver klynge, der fortsætter tjenesten og leverer billedwebadressen i ECR.

implementeringsworkflow

Det er virkelig det til implementering! bare et facilitatorjob mellem to AWS-produkter, lad os sammenligne denne workflow med det, vi havde før, og se hvordan vores frigivelsesstrategi ændrede sig.

Brug af den nye proces til at implementere din kode på nogen af ​​trinene (prod, dev, staging) kræver ikke nogen form for fusionerer , -koden er helt uafhængig af implementering , vi kunne have 20 funktioner klar på mastergrenen og vælger kun at distribuerer 10 af dem.

Men dette indebærer også, at vi kun kan have en funktion, der er testet på dev-grenen, medmindre to devs blev enige om at rebase på hinanden.

Implementeringshistorik og tagging

Dette gav os også en bedre tilbageførsel strategi mod produktionsproblemer. Nu har vi en tagget masterfilial for hver -funktion / opgave vi havde, hver gang vi står over for et produktionsproblem og ønsker at tilbageføre en funktion, kan vi nemt navigere tilbage til, hvor denne funktion startede, og tilbagevenden til forpligtelsen før den, hvis det er muligt. > Også det tillod os at fusionere alle funktionsfunktioner i mastergrenen, selvom de ikke vil blive implementeret, kan vi stadig have dem på master klar til det næste parti funktioner, der skal være i produktion, når det er nødvendigt, hvilket helt sikkert vil hjælpe vores team fokuserer på at levere opgaver uden at bekymre sig om, hvornår den opgave vil blive flettet til master, der skal implementeres, her fusionerer vi først og derefter bekymrer os om implementeringer.

Næste trin

Vi arbejder i øjeblikket på at automatisere vores proces bedre, inklusive miljøvariabler og maskinspecifikationer, vil de alle være tilgængelige som kode, når vi ændrer disse specifikationer, vil det automatisk reflektere ect på vores maskiner på AWS i det respektive Miljø , det er ikke nødvendigt at håndkode disse værdier hver gang på AWS.

Med dette får vi bedre kontrol og synlighed på alle vores servicekonfigurationer, alt i vores infrastruktur vil være i kode og et klik væk for at opdatere! også det, der gør det at ændre vores infrastruktur uafhængigt af tjenesteudbyderen, kunne vi f.eks. skifte fra AWS til Google cloud og behøver kun at ændre de kommandoer, der bruges af implementeringstjenesten til at implementere vores infrastruktur på den nye tjenesteudbyder.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *