Fejlesztési és CI/CD folyamatok gyorsítása Daggerrel (példakódokkal)

Címkék

Sági-Kazár Márk előadása az AWS Lounge Hungary meetup sorozat 2024. december 12-i, "60 minutes of CI/CD automatizations" állomásán hangzott el. Az elmúlt évek egyik legnagyobb kihívása a platformok és környezetek közötti könnyű átjárás biztosítása volt, melyet végül a konténerekkel a Docker forradalmasított a szoftverdisztribúció területén. De mi a helyzet a fejlesztés többi részével? Eleged van az eltérő környezetekből és az inkonzisztens build eredményekből? Frusztrál, hogy órákat kell töltened új fejlesztői környezetek beállításával vagy azzal, hogy miért törik el egy script a CI-on, miközben lokálisan fut? Gyorsan ki kellene adni egy fixet, de a CI épp nem fut? Erre próbál hordozható megoldást nyújtani a Docker alapítójának, Solomon Hykes-nak a legújabb projektje, a Dagger, ami egy nyílt forráskódú, hordozható CI/CD engine.

Hozzászólások

Szerkesztve: 2025. 01. 17., p – 00:21

Erdekes koncepcio, de nem gyozott meg, hogy tenyleg hasznos lenne szamunkra.

Egy Makefile-lal athidalhato az emlitett problemak jelentos resze. Keszitunk minden CI stepre make rule-t: build, test, lint, scan, run, push, deploy, ...
Ugyanazon `make akarmi` parancsot hasznalja a CI pipeline, amit a fejleszto is tud futtatni lokalban (fuggoen attol, hogy mihez van hozzaferese). Ennyi.

A kihivas sokkal inkabb abbol ered, hogy idovel egyre tobb managed AWS service-t hasznalunk, amikhez nem ferhet a fejleszto hozza lokalbol. Ezert muszaj vagyunk szimulalni:

  • EKS-t Kind clusterral (helm chart tesztje miatt)
  • RDS-t konnyen ki tudunk valtani helyi postgressel/mysqllel, amit mondjuk docker compose-zal inditunk es inicializalunk
  • ElastiCache-re local Redis
  • S3-ra van minio vagy localstack
  • DynamoDB-re is localstack
  • secret managementet probaljuk kikerulni lokalban dummy jelszavak hasznalataval

De meg mindig fennall az a problema, hogy mikent toltsuk fel ezeket eletszeru adatokkal, hogy a fejleszto ne ures adatokkal dolgozzon.

Ezek megoldasa szerintem fontosabb, mint hogy go-ban kodoljuk le azt, amit siman megtehetunk egy shell scriptben/makefile-ban.

Egy Makefile-lal athidalhato az emlitett problemak jelentos resze.

És behozol egy csomó más problémát... egyrészt a Makefile az igazán nem cross-platform, másrészt egy csomó nyelv és platform esetén nem is illeszkedik (jól) a workflow-ba. Ahol a Dagger szóba kerül, ott tipikusan nincs C/C++, ahol a Makefile natív build eszköz.

amikhez nem ferhet a fejleszto hozza lokalbol

Egyre inkább az van, hogy a fejlesztő nem local dolgozik ilyen projekteken, hanem kap a fejlesztés idejére egy komplett környezetet branch szinten létrehozva és minden commit kimegy oda, akár élesbe menne.

De a Makefile-t nem kell arra hasznalni, amire eredetileg valo (C/C++ dependency szerinti buildeles), csak egy eszkoz, amivel osszefogjuk a kis scriptelt lepeseket. De ott van a videoban emlitett `just` is, az is jo lehet.
De lehet a repo gyokereben `./test.sh`, `./lint.sh`, ... is.

kap a fejlesztés idejére egy komplett környezetet branch szinten létrehozva és minden commit kimegy oda

Ez tul lassu szerintem. Csak egy EKS cluster letrehozasa majd 10 perc. Ha felteszunk ra minden observability eszkozt (logging, monitoring, tracing, profiling), akkor kozelitjuk a fel orat. Azert az tulzas, hogy egy egy soros change miatt fel orat varni kelljen a CI-ra.

Akkor mar inkabb jobb az a modszer, hogy minden PR-hoz keszul egy uj K8s namespace, akkor a tobbi parhuzamos PR-ral nem akad ossze (legalabbis helm szinten). Namespace-t gyorsan lehet letrehozni es torolni.

Nehezebb ugy, ha egy PR adatbazis schemat modosit, mert nyilvan nem szeretnenk adatbazist clone-ozni minden PR szamara.

De a Makefile-t nem kell arra hasznalni, amire eredetileg valo (C/C++ dependency szerinti buildeles), csak egy eszkoz, amivel osszefogjuk a kis scriptelt lepeseket. De ott van a videoban emlitett `just` is, az is jo lehet. De lehet a repo gyokereben `./test.sh`, `./lint.sh`, ... is.

Antipattern és nem is hatékony egy csomó esetben. Kicsit olyan, mint ahogy a Fortran programozók minden nyelvek tudnak Fortran programot írni...

Ez tul lassu szerintem. Csak egy EKS cluster letrehozasa majd 10 perc. Ha felteszunk ra minden observability eszkozt (logging, monitoring, tracing, profiling), akkor kozelitjuk a fel orat. Azert az tulzas, hogy egy egy soros change miatt fel orat varni kelljen a CI-ra.

Ez úgy működik jó esetben, hogy a branch létrehozásakor létrejön a környezet. Lehet, hogy 10 perc, de létrehozott feature branch-en ritkán dolgozol 10 percnél rövidebb ideig, a quickfix branch meg más témakör. És egy-egy sor change kurva gyorsan végig tud menni megfelelő architektúra és pipeline esetén.

Akkor mar inkabb jobb az a modszer, hogy minden PR-hoz keszul egy uj K8s namespace, akkor a tobbi parhuzamos PR-ral nem akad ossze (legalabbis helm szinten). Namespace-t gyorsan lehet letrehozni es torolni.

A PR az kb. branch szintű dolog ideális esetben (sok esetben ez teljesen automatikus issue-branch-PR/MR triót jelent). Pont erről van szó.

Nehezebb ugy, ha egy PR adatbazis schemat modosit, mert nyilvan nem szeretnenk adatbazist clone-ozni minden PR szamara.

Miért nem? A fejlesztő mit csinál a saját gépén egyéb esetben, milyen DB-t használ?

Ez úgy működik jó esetben, hogy a branch létrehozásakor létrejön a környezet.

Tehat ha pentek delutan letrehozok egy branchet es nem fejezem be aznap, akkor egesz hetvegen at fog egy fullos EKS futni a cloudban? Mert ez igy nagyon nem tunik koltseghatekonynak.

Pont erről van szó.

Pont nem. Nagyon mas, ha minden egyes PR/branch-re egy fullos EKS-t deployolsz vagy csak egy namespace-t az appnak, minden mas shared.

Miért nem? A fejlesztő mit csinál a saját gépén egyéb esetben, milyen DB-t használ?

A DB schema is verziokezelt, abbol inicializalhato a helyi DB. Vmi minimalisztikus tesztadatot is betoltunk nehol.

A gond ugye az, hogy a tesztadatban nincsennek olyan meglepetesek, mint ami egy real-life DB-ben elofordulnak.

Tehat ha pentek delutan letrehozok egy branchet es nem fejezem be aznap, akkor egesz hetvegen at fog egy fullos EKS futni a cloudban? Mert ez igy nagyon nem tunik koltseghatekonynak.

Azért szerintem abban egyet tudunk talán érteni, hogy nem túl nehéz rule-t készíteni arra, hogy feature branch környezete munkaidőn kívül ne fusson. De amúgy ezek nem nagy költségek általában ahhoz, hogy egy fejlesztő mennyi idő el tud baszni azzal, hogy nincs fejlesztéshez használható környezete.

Pont nem. Nagyon mas, ha minden egyes PR/branch-re egy fullos EKS-t deployolsz vagy csak egy namespace-t az appnak, minden mas shared.

Ez már részletkérdés, hogy namespace vagy resource, ha van K8s, akkor nyilván egyszerűbb dedikált namespace az összes függőségével együtt, de amúgy pay-as-you-go resource is ugyanúgy indítható és leállítható.

A DB schema is verziokezelt, abbol inicializalhato a helyi DB. Vmi minimalisztikus tesztadatot is betoltunk nehol.

És ez akkor miért nem kivitelezhető egy felhős környezetben is?

A gond ugye az, hogy a tesztadatban nincsennek olyan meglepetesek, mint ami egy real-life DB-ben elofordulnak.

Ennyivel jobb a megfelelően karbantartott felhős fejlesztői környezet, hogy ott lehetnek bőven adatok.

És ez akkor miért nem kivitelezhető egy felhős környezetben is?

Mert nem szeretnenk semmilyen felhoben futo DB-t expose-olni public IP-ra, hogy a developer lokalisan fejlesztett es buildet progijaval elerje. Nyilvan lehetne mindenfele SSH port-forwardokkal/tunnellel trukkozni, csak ez mar megint olyan dolog, amivel egy random developer nem akar foglalkozni. Szoval egyszerubb ha lokalban inditunk postgrest teszt adatokkal.

Mert nem szeretnenk semmilyen felhoben futo DB-t expose-olni public IP-ra, hogy a developer lokalisan fejlesztett es buildet progijaval elerje.

Egyrészt van felhőben private network, másrészt tudod tenni helyben is, akár csak a fejlesztő.

Nyilvan lehetne mindenfele SSH port-forwardokkal/tunnellel trukkozni, csak ez mar megint olyan dolog, amivel egy random developer nem akar foglalkozni. Szoval egyszerubb ha lokalban inditunk postgrest teszt adatokkal.

Egy VPN miért trükközés? 2025 elején járunk. Random developernek miért okoz problémát egy VPN kapcsolat és egy postgres indítása miért nem?

Ez megy Makefile nélkül is egyrészt, másrészt meg kockázat, mert eltérő koncepció és teljesen külön életet él, mint az első élesre hasonlító környezet, könnyen rejtett problémák maradnak a fejlesztésekben és az ismét csak költség, költség és költség. Enyhén úgy érzem, hogy nem történt meg a paradigmaváltás, hogy miről is szól ez az egész.

Bocs, de mar elvesztettem a fonalat, hogy mivel is van bajod es itelkezel masok felett.

Nincs ítélkezés, ez a leírtak alapján egy szimpla ténymegállapítás, hogy nem történt meg a paradigmaváltás.

Mindenesetre azt belathatjuk, hogy ez a Dagger pont olyan "problemat" akar megoldani, ami nem szokott problema lenni. A CI/CD komplexitasa mashol van.

Én nem látom ezt be. A Dagger egy másik CI/CD paradigma eszköze, amit nyilván teljesen értelmetlennek, feleslegesnek és haszontalannak látsz, ha egy korábbi paradigma alapján van felépítve az architektúrád, amibe bele próbálod képzelni. Amint megtörténik a paradigmaváltás, rögtön értelmet, szükséget és hasznot látsz majd.

Te hasznalod egyebkent?

Igen.

Csak mert ugy emlekszem, hogy javas vagy, szoval ez egy idegen toolnak tunik.

Nem a Dagger készíti el a war fájlokat amúgy, az messziről nézve egy CI/CD orchestrator, ilyemit kell elképzelni: 

return dag.Java().
	WithJdk("17").
	WithMaven("3.9.5").
	[...]

Van ennek a paradigmanak neve egyebkent? Nyitott vagyok az ujdonsagok fele, csak jo lenne latni a hasznat, anelkul aligha kezdjuk el hasznalni.

Nincs igazából neve szerintem, egyszerűen másképp kell gondolkodni, mint például Java esetén anno az Ant - Maven váltás esetén is; vagy akár az utóbbi években a klasszikus üzemeltetés vs Ansible/Terraform/Puppet/whatever kapcsán. Fuss neki, próbáld ki, szerintem ki fog esni, hogy jó cucc és az is, hogy mit kellene másképp csinálni és az miért jobb, mint ahogy most vannak a dolgok. Azt a hibát érdemes elkerülni, hogy úgy használod, ahogy eddig ment minden, abból lettek anno azok a Maven projektek, amelyek Ant parancsokat futtattak végül. Szóval a Dagger nem arra jó, hogy az futtasson shell parancsokat.

Ismét egy olyan projekt, ami azzal próbálja megoldani, hogy a sokféle tool összeveszik egymással, hogy hoz egy újabb toolt :D

Lehet tulk oreg vagyok, de hosszu Jenkins-ezes utan nem tudnak meggyozni ezek a tool-ok. Mind olyan vegtelenul fapados a Jenkins utan viszont pilotavizsgas a Jenkinshez kepest, hogy nem erzem a hivast, hogy energiat fektessek belejuk. Persze mi is hasznalunk gitlab/github pipeline-okat, do olyanok azok, mintha kalapaccsal kellene bokszkesztyuben tortat szelni es kiosztani. 

A make-et meg sokan lenezik (juniorjaink azt sem tudjak mifasz az), de egy make rendszerrel azert egesz szep nagy es bonyolult workflow-kat lehet leirni. Es itt most nem kell csak a gnu make-re gondolni, de ott a maven, gradle es tarsai is.