Skip to main content
2023-07-03

Det optimala IT-utvecklingsteamet 5 - CI CD

2023-07-03

I de tidigare artiklarna i denna serie diskuterade vi hur du kan samla in verksamhetens behov/krav och sedan konkretisera dessa i mätbara mål. Vi diskuterade också hur ett utvecklingsteam kan bemannas upp och vilka kompetenser/erfarenheter vi ska fokusera på och hur dessa är kopplade till målen.

Jag kom också in på de agila principerna och Scrum och hur du kan komma igång med att använda det i praktiken. I nästföljande artikel pratade jag lite om kommunikation, samarbete och hur viktigt det är att lära känna varandra. I den här artikeln tänkte jag berätta lite om hur du kan implementera CI/CD-tänket i ditt team och hur det kan bidra till att teamets leveranser alltid är uppdaterade.

Den ädla konsten att rekrytera, bygga och sätta ihop det optimala IT-utvecklingsteamet

Continuous integration (CI)

Att komma igång med CI på riktigt kräver en del förberedelse. Som t.ex. att sätta upp ett repository där alla utvecklare kan checka in koden de arbetar med. Några populära produkter för att dela kod är Github, Gitlab och Bitbucket. Med tanke på att det numera är Microsoft som äger Github kanske många känner lite oro över att lägga all sin källkod i knät på dem, som tur är kan du ju också välja att ha en lokal installation där du inte lägger koden i händerna på ett externt företag. När du väl har bestämt dig för hur du ska hantera teamets källkod och hur den lagras och versionshanteras är det dags att börja fundera på hur du kan automatisera byggandet och testandet. I en traditionell utvecklingsmiljö skapar utvecklarna sin kod, kompilerar ihop detta till binära exekverbara filer och sedan kan detta installeras och startas upp i en testmiljö där det sedan testas både automatiskt och manuellt. Nackdelen med detta tillvägagångssätt är att det blir väldigt personberoende och utsatt för risken att mänskliga faktorn börjar spela in. Människor är inte riktigt gjorda för att utföra monotona, okvalificerade uppgifter, men för en dator är det lika med den perfekta dagen på jobbet.

Det finns en flora av verktyg för att underlätta arbetet med CI och flera av dessa är knutna till den källkodshantering du väljer att tillämpa. Men för att räkna upp några populära verktyg värda att nämna så har vi Jenkins, Argo CD, Tekton, CircleCI, GitLab CI, Github Actions, FluxCD med flera. Nu är det inte helt enkelt att kategorisera dessa verktyg eftersom deras funktionalitet flyter in på flera andra områden, men om du studerar dessa verktyg och gör lite sökningar på nätet kommer du att hitta mängder med konkreta exempel på hur du kan sätta upp det och få en smidig CI-miljö.

Nästa steg är att se till att kompilera och bygga källkoden automatiskt och det beror ju lite på vilken utvecklingsmiljö du använder dig av och vilka programmerings- eller scriptspråk du använder dig av. Egentligen är det ingen skillnad mellan att kompilera och bygga allting manuellt eftersom det är exakt samma steg du behöver definiera i det automatiserade flödet. Så om du t.ex. bygger dina Java-baserade applikaioner med Maven är det också det du ska definiera i det automatiserade flödet.

Automatiserade tester

Automatiserade tester

Ett mycket komplext område handlar om automatiseringen av de tester vi behöver utföra för att koden ska anses vara tillräckligt mogen och redo för att kunna driftsättas till produktion. De flesta känner ju till den klassiska testpyramiden med unit tester längst ner, integrationstester på våning två och högst upp end-to-end tester. Men det som inte är med som självklara delar i testpyramiden är prestandatester, applikationssäkerhetstester och penetrationstester. Det finns också många olika delar i de olika testaktiviteterna vilket gör det ännu mer komplext. Som tur är finns det även inom detta område mängder av verktyg vi kan nyttja för att automatisera testandet. För att t.ex. scanna igenom statisk källkod kan du använda verktyg som SonarQube, Raxis, Kiuwan, Parasoft, Embold, Veracode med flera. Listan kan göras lång.

När koden väl har testats kan du också scanna igenom dina artefakter (images) med hjälp av verktyg som kan läsa dessa. Exempel på verktyg inom denna genre är Jfrog Xray, Octopus, PyCharm, Datadog etc. Även inom detta område finns det en hel hög med verktyg du kan använda dig av så det bästa är väl att du bildar dig en egen uppfattning och väljer det som passar bäst.

Utvecklarna själva skriver sina enhetstester som är på betydligt lägre nivå och testar enskilda metodanrop och t.ex. ser till att korrekta parametrar returneras. Med hjälp av scanningsverktygen jag pratade om tidigare finns det möjlighet att sätta upp så kallade toll gates som kräver en viss täckning av de enhetstester som skrivits. På det viset kan du t.ex säga att minst 75% av koden måste vara täckt med enhetstester innan den kan godkännas och skickas vidare. Problemet med dessa hårda gränser är dock att det blir enkelt för en utvecklare att skriva tester bara för att det måste göras och inte så mycket för att kvalitetssäkra koden. Vad jag menar med det är att jag som utvecklare kanske skickar upp min källkod och får svaret att det endast är 73% täckning och det krävs 75%. Då kan jag enkelt snickra ihop några enhetstester som anropar metoder i min källkod men som kanske är helt irrelevanta för att applikationen ska fungera, men ändå bidrar det till att jag plötsligt får 76% täckning och passerar kontrollen.

Nåja, man kan diskutera automatiserade tester hur länge som helst. Det viktiga att ha i åtanke är att du hela tiden ska se till du testar tillräckligt mycket för att kunna garantera produktens kvalitet så mycket att du med gott samvete kan trycka ut den i produktion. Samma sak gäller de övriga testområden jag räknade upp innan. Det svåraste (näst intill omöjliga) området att testa är den explorativa testningen, men till viss del kanske detta underlättas med nya moderna AI-verktyg, men i dagsläget finns tyvärr inget tillräckligt effektivt testverktyg för den typen av testning såvitt jag vet.

Continuous Deployment (CD)

Så har vi då kommit fram till sista steget när vi faktiskt ska få ut vår applikation i produktion så att alla kan börja använda den. Precis som med den automatiserade testningen behöver du även här tänka igenom vilka steg du behöver utföra för att applikationen ska driftsättas i produktion. Här kan du också tänka likadant och se till att du först driftsätter till dina staging-miljöer. Ett vanligt scenario är att man har en utvecklingsmiljö där all laboration och nyutveckling sker, sedan går detta till en systestmiljö där även andra utanför teamet kan testa applikationen, därefter kan du driftsätta till en acceptanstestmiljö där du kanske också blandar in vissa externa användare som får vara med och testa. När du väl vet vilka steg som behöver utföras kan du automatisera detta i de CI-verktyg du använder.

Det som kan vara lite klurigt är när driftsättningen inte bara gäller nya applikationer som ska driftsättas utan också konfigurationsändringar som behöver utföras för att den nya versionen ska kunna startas upp och användas. Men tappa inte modet! Även detta kan ’enkelt’ hanteras med lite olika verktyg och på lite olika sätt. Enklare verktyg som Puppet, Ansible, Terraform och Chef kan du använda för att uppdatera konfiguration på många system samtidigt och med ett strukturerat arbetssätt. Mer avancerade verktyg omfattar produkter som Kubernetes och Docker Swarm där du dessutom virtualiserar de olika systemen där dina applikationer körs vilket får till följd av även själva ’servrarna’ kan hanteras som kod. Och sist men inte minst kan du också komplettera med ett grafiskt skal ovanpå dessa verktyg. För Kubernetes finns t.ex. OpenShift från Red Hat där du enkelt kan sköta om din serverpark som består av små så kallade podar där alla applikationer körs i ett containerbaserat ekosystem.

I denna artikelserie ska jag försöka att inte dyka ner så mycket på djupet kring olika tekniska paradigmskiften, men jag tänker att det ändå kan vara bra att ha en grundläggande förståelse för olika tekniker och få ett hum om vad man kan och inte kan göra med dagens teknik. Precis som allt annat är det även här viktigt att arbeta med ständiga förbättringar och hela tiden undersöka hur du kan effektivisera din driftsättningsprocess och samtidigt kvalitetssäkra den mer och mer.

Men hur är det när allting inte fungerar så smärtfritt i teamet? Det tänkte jag diskutera i nästa artikel och utmaningarna med att hantera konflikter, stress och andra hinder i teamet.

Written by André Johansen