Blog

Bemästra DevOps med AI: Bygg CI/CD-pipelines på nästa nivå

JAN 9, 2024

I en tid då AI-assisterad programmering utvecklas snabbt går det inte att överskatta vikten av robusta DevOps-metoder. I det här blogginlägget visar jag hur du kan använda AI effektivt för att bygga och förbättra CI/CD-pipelines, och belyser att även om AI medför betydande framsteg är mänsklig expertis fortfarande avgörande.

Alex Jantunen

Alex is an experienced software architect specializing in solving complex problems and optimizing CI/CD pipelines. He is particularly skilled in microservices, backend, and DevOps.

Att etablera en stabil DevOps-grund är inte längre ett projekt som tar månader. Med rätt arbetssätt och verktyg kan, och bör, även små projekt ha en välfungerande DevOps-struktur på plats inom dagar eller veckor. Låt oss nu fokusera på grunderna i CI/CD och börja med Git-workflowet.

image-1

Git-workflow: Grunden för bra CI/CD

Som vi alla vet är tydliga och väldokumenterade Git-workflows avgörande för alla framgångsrika utvecklingsprojekt, särskilt inom DevOps. Här visar jag hur du kan skapa ett från grunden med hjälp av ChatGPT 4. Du kan testa resultaten med exakt samma prompts som jag har använt här (ChatGPT 4 krävs).

Prompt #1

Den första prompten fungerar vanligtvis som en introduktion till ämnet. Med det här tillvägagångssättet kan du se det första svaret och förstå diskussionens riktning. En enskild prompt räcker sällan. Läs vidare för att se hur jag guidar diskussionen vidare. Min första prompt är följande:

Please give me git workflow baseline so that I can later implement continuous integration and deployment pipelines on top of the workflow practices

GPT-svar

Creating a solid Git workflow baseline is essential for implementing continuous integration (CI) and continuous deployment (CD) pipelines effectively. Here's a suggested baseline workflow that you can use as a starting point:...

Branchstrategi:

  • Huvudbranch: Detta är den primära branchen där källkoden i HEAD alltid återspeglar ett produktionsklart tillstånd.

  • Develop-branch: Den här branchen fungerar som en integrationsbranch för funktioner. Den innehåller alltid de senaste levererade utvecklingsändringarna för nästa release.

  • Feature-brancher: Skapa dessa brancher när du börjar arbeta med en ny funktion. Utgå från 'develop' och merga tillbaka till 'develop' när funktionen är klar.

  • Release-brancher: Utgå från 'develop' när du är redo att förbereda en ny produktionsrelease. Det gör att ett team kan finslipa den aktuella releasen medan ett annat team fortsätter arbeta med funktioner till nästa release.

Hotfix-brancher: Dessa brancher används för att snabbt åtgärda produktionsreleaser. De liknar release- och feature-brancher, men utgår från 'main' och mergas in i både 'main' och 'develop'.

Continuous Integration (CI):

  • Konfigurera en CI-pipeline som kör automatiserade tester och andra kontroller, till exempel linting, varje gång en ny commit pushas till en branch – särskilt till 'develop' och feature-brancher.

Continuous Deployment (CD):

  • När CI-pipelinen har godkänts och ändringarna har mergats in i main-branchen kan du automatiskt driftsätta till produktion, om din konfiguration tillåter det.

  • För miljöer som kräver mer kontroll kan du välja att manuellt trigga driftsättningar från main-branchen.

Versionsmärkning:

  • Tagga koden i main-branchen med ett versionsnummer efter varje release.

Dokumentation:

  • Håll projektets dokumentation uppdaterad. Det gäller inte bara kodens dokumentation, utan även era workflow- och pipelineprocesser.

Dessutom finns avsnitt om riktlinjer för commits, kodgranskning och mergning, men vi fokuserar inte på dem i det här blogginlägget, även om de är viktiga.

Slutsats om att använda en grundläggande Git-workflow

Även AI verkar betona vikten av Git-workflows. Den föreslår separata utvecklings- och releasebrancher, vilket är en bra strategi när den implementeras på rätt sätt. Men för demonstrationens skull visar jag ett mer förenklat workflow som kan vara mer optimalt.

Observera den viktiga aspekten: Dokumentera ditt workflow och din pipeline! Här verkar AI:s resonemang vara mycket väl genomtänkt och oftast bättre än verkligheten.

Tydlig kommunikation om dessa ämnen och retrospektiv säkerställer en fortsatt bra Developer Experience (DevEx).

Prompt nr 2

Nu när vi har det första svaret och ChatGPT har vår diskussionshistorik sparad inför framtida promptar planerar jag att be om mer specifika detaljer. Det är klokt att utvärdera svaret efter den första prompten och efter varje efterföljande svar, samt vid behov fördjupa sig i nya ämnen som uppstår.

Först därefter bör du gå vidare med nästa prompt för att undvika att störa chattsessionen, vilket lätt kan leda till oönskade resultat med stora språkmodeller (LLM:er). 

Gör workflowet enklare och ta bort develop- och releasebrancher. Till dessa kommer jag att använda Git-taggar.

GPT-svar

Absolut! Att förenkla Git-workflowet genom att ta bort develop- och releasebrancherna och i stället använda Git-taggar kan göra processen smidigare, särskilt för mindre team eller projekt. Här är en reviderad version av workflowet:

Main-branch:

  • Detta är din primära och enda långlivade branch. Main-branchen representerar det produktionsklara tillståndet för din kod.

  • Alla funktioner, buggfixar och hotfixar mergas direkt till denna branch.

Feature-brancher:

  • Skapa en feature-branch varje gång du börjar arbeta med en ny funktion eller en buggfix.

  • Utgå från main och merga tillbaka till main när arbetet är klart och testat.

  • Namngivningskonventionen för feature-brancher kan exempelvis vara feature/<feature-name> eller bugfix/<bug-name>.

Git-taggar för releaser:

  • När du är redo att släppa en ny version använder du Git-taggar på main-branchen.

  • Namnge dina taggar med semantisk versionshantering (t.ex. v1.0.0, v1.0.1) för att hålla koll på olika releaser.

  • Taggar kan också användas för att trigga specifika CI/CD-åtgärder vid behov.

Continuous Deployment (CD):

  • Om projektets konfiguration tillåter det kan du konfigurera CD för att automatiskt driftsätta main-branchen till produktion efter godkända CI-kontroller.

  • För miljöer som kräver mer kontroll kan du välja att driftsätta taggade versioner manuellt.

De övriga delarna är mycket lika de tidigare och behöver inte upprepas här.

Slutsats om att förenkla workflowet och ta bort develop- och releasebrancher

Okej, nu ser det ut som jag bad om. Men det uppstår en farhåga när GPT föreslår att main-branchen automatiskt driftsätts till produktion efter CI.

Vi vet alla att vi, för att behålla vårt förstånd och systemens tillförlitlighet, behöver produktionslika miljöer, till exempel staging, för korrekt kvalitetssäkring (QA).

Det är avgörande att köra automatiserade regressionstester i produktionslika miljöer efter varje ändring. Det omfattar inte bara kodändringar i produkten, utan även ändringar som rör infrastruktur (IaC), pipelines och annat.

Prompt #3

För Continuous Deployment vill jag att endast main automatiskt driftsätts till produktionslika miljöer, exempelvis staging. En driftsättning till produktion ska ske genom Git-taggar med prefixet "release-", till exempel release-v1.0.0. För driftsättning till staging skulle prefixet vara rc- (release candidate).

GPT-svar

Absolut, din metod för Continuous Deployment med specifika Git-taggkonventioner för staging- och produktionsmiljöer är en utmärkt strategi. Så här kan du strukturera arbetsflödet:

Main-branchen som staging-miljö:

  • Main-branchen fungerar som en staging-liknande miljö. Varje merge till main utlöser en automatisk driftsättning till staging-miljön.

  • Det gör att du kan testa i en miljö som ligger nära produktion.

Git-taggar för staging och produktion:

  • Staging-taggar: Använd prefixet rc- (release candidate) för driftsättningar till staging. Till exempel anger rc-v1.0.0 en release candidate för version 1.0.0. När du pushar en tagg med det här prefixet utlöser den en driftsättning till staging-miljön.

  • Produktionstaggar: Använd prefixet release- för driftsättningar till produktion. Taggar som release-v1.0.0 används för att utlösa manuella driftsättningar till produktionsmiljön. Det ger dig kontroll över vad som driftsätts till produktion och när.

Steg i arbetsflödet:

  • Utveckling: Utvecklare arbetar i feature- eller bugfix-brancher som utgår från main.

  • Kodgranskning och merge: När arbetet är klart skapas en pull request för att merga ändringar till main. Efter kodgranskning och godkända CI-kontroller mergas ändringarna.

  • Automatisk driftsättning till staging: En merge till main utlöser automatiskt en driftsättning till staging-miljön. Detta sker för slutlig testning och validering.

  • Taggning för release candidates: När teamet är nöjt med ändringarna i staging skapas en rc-tagg för att formellt markera en release candidate.

  • Driftsättning till produktion: När release candidaten har testats grundligt och godkänts skapas en release-tagg. Den taggen används sedan för att manuellt utlösa driftsättningen till produktionsmiljön.

Continuous Integration och deployment:

  • Konfigurera CI/CD-pipelines för att hantera olika miljöer utifrån taggningskonventionen.

  • Säkerställ att CI-pipelinen innehåller alla nödvändiga tester och kvalitetskontroller.

Dokumentation:

  • Dokumentera processen tydligt, inklusive hur och när du ska tagga för driftsättningar till staging och produktion.

Det här upplägget ger en tydlig åtskillnad mellan driftsättningar till staging och produktion och ger teamet kontroll över releaseprocessen. Genom att använda olika taggar för staging (rc-) och produktion (release-) kan du enkelt hantera och följa olika releasears framsteg genom era miljöer.

Slutsats om att automatisera driftsättningar till produktionsliknande miljöer

Nu är jag nöjd med mitt arbetsflöde. Det går att arbeta på liknande sätt för att skapa ett arbetsflöde som du känner dig nöjd med att gå vidare med.

Om du helt trasslar till chattsessionen med AI kan det vara bättre att börja om från början med en ny session för att undvika missvisande svar.

Den här gången lyckades jag få resultat i den första chattsessionen, men många gånger var det inte lika enkelt. Härnäst går jag vidare med att faktiskt generera pipeline-koden med Atlassian Bitbucket Pipelines som underliggande teknik.

Generativ AI för DevOps-pipelines

I det här avsnittet ska vi se hur Chat GPT-4 kan generera en beskrivningsfil för en Bitbucket-pipeline för att implementera ovanstående.

Prompt #4

Här fortsätter jag att skriva promptar i samma chattsession, så att LLM:en har relevant kontext i bakgrunden.

Nu vill jag att du ger mig bitbucket-pipelines.yaml utifrån det senaste arbetsflödet som du nyligen svarade med. Ange pipelinen för min backend-tjänst som är implementerad med Python Flask, och jag vill driftsätta till Google Kubernetes på GCP.

Här fick jag en övergripande implementation där de flesta detaljer hade flyttats till separata shellskriptfiler. Det var inte min avsikt, så jag visar inte svaret här. Efter ytterligare diskussionsrundor fick jag dock det jag letade efter.

Prompter från #5 till #8

Flera prompter är vanliga när man använder generativ AI för komplexa ämnen. AI:n kan inte utläsa dina exakta behov från en enda prompt med begränsad detaljnivå. Dessutom är det viktigt att dela upp större uppgifter i mindre, hanterbara delar. Processen kräver också en god förståelse för DevOps för att kunna styra samtalet effektivt. Du bör inte förvänta dig att enkelt få bra resultat.

#5 - Okej, detta är lite för övergripande. Jag vill att du inkluderar byggande av Docker-images och pushning av images till Google Cloud Repository gcr.io. Inkludera även kommandon för gcloud CLI och kubectl. Lägg också till platshållare för miljövariabler och hemligheter där det behövs.

#6 - Det är bra, men hur fungerar det om taggen release-* triggas manuellt?

#7 - Jag vill börja använda Bitbuckets deployment environments. Kan du ge mig den senaste bitbucket-pipelines.yaml-filen med ändringarna som inkluderar denna information?

#8 - Jag vill ändra pipelinen så att Docker-imagen bara byggs en gång och sedan kan taggas om. Det ska inte behövas att bygga den på nytt.

Svar från GPT-4

För att ändra din pipeline så att Docker-imagen bara byggs en gång och sedan taggas om för olika miljöer behöver du göra några justeringar i din bitbucket-pipelines.yml. Tanken är att bygga Docker-imagen en gång, pusha den till Google Container Registry (GCR) med en generell tagg och sedan tagga om den för driftsättning till staging eller produktion vid behov.

Här är en uppdaterad version av din bitbucket-pipelines.yml-fil med dessa ändringar:

image: atlassian/default-image:2
pipelines:
  default:
    - step:
        name: Build and Test
        caches:
          - pip
        script:
          - pip install -r requirements.txt
          - python -m unittest discover tests
  branches:
    main:
      - step:
          name: Build and Push Docker Image
          script:
            - echo $GCLOUD_SERVICE_KEY | base64 --decode --ignore-garbage > ${HOME}/gcloud-service-key.json
            - docker build -t gcr.io/$GCLOUD_PROJECT/your-app:latest .
            - gcloud auth configure-docker --quiet
            - docker push gcr.io/$GCLOUD_PROJECT/your-app:latest
      - step:
          name: Deploy to Staging
          deployment: staging
          script:
            - echo "Deploying to Staging Environment"
            - ./deploy-staging.sh # This script should handle the retagging for staging
  tags:
    'rc-*':
      - step:
          name: Retag and Deploy to Staging
          deployment: staging
          script:
            - echo "Retagging and Deploying Release Candidate to Staging"
            - ./retag-deploy-staging.sh # Script to retag the image for staging
    'release-*':
      - step:
          name: Retag and Deploy to Production
          deployment: production
          trigger: manual
          script:
            - echo "Retagging and Deploying to Production Environment"
            - ./retag-deploy-production.sh # Script to retag the image for production
definitions:
  caches:
    pip: ~/.cache/pip

Viktiga ändringar

Bygg en image en gång: Docker-imagen byggs och pushas bara en gång vid commits till main-grenen. Den taggas som latest.

Omtaggning för staging och produktion:

  • Skriptet ./deploy-staging.sh används för att driftsätta den senaste taggen direkt till staging-miljön.

  • För taggarna rc-* och release-* används separata skript (./retag-deploy-staging.sh och ./retag-deploy-production.sh). Dessa skript ska hantera omtaggningen av Docker-imagen med rätt tagg, baserat på commit- eller release-taggen, och sedan driftsätta den till respektive miljö.

Skript för omtaggning och driftsättning

  • ./deploy-staging.sh ska driftsätta den senaste imagen till staging utan att tagga om den.

  • ./retag-deploy-staging.sh och ./retag-deploy-production.sh ska:Göra en pull av den senaste imagen från GCR.Tagga om den med den specifika commit- eller release-taggen.Pusha tillbaka den omtaggade imagen till GCR.Uppdatera Kubernetes-deploymenten så att den använder den nya taggen.

  • Gör en pull av den senaste imagen från GCR.

  • Tagga om den med den specifika commit- eller release-taggen.

  • Pusha tillbaka den omtaggade imagen till GCR.

  • Uppdatera Kubernetes-deploymenten så att den använder den nya taggen.

Det här tillvägagångssättet säkerställer att Docker-imagen bara byggs en gång, vilket sparar tid och resurser. Skripten för omtanggning ger flexibilitet att hantera olika miljöer utan att behöva bygga om imagen. Kom ihåg att säkerställa att ditt GCP-tjänstkonto har nödvändiga behörigheter och att ersätta platshållare med dina faktiska projektuppgifter.

Slutsats för slutligt resultat från LLM

Upprepa dessa steg för varje komponent i ditt system, oavsett om det är en tjänst, ett UI eller en applikation. Utifrån min erfarenhet av Bitbucket-pipelines kan jag med en ganska hög grad av säkerhet utvärdera svar och förstå vad som krävs för att få detta i drift. Om jag däremot inte var bekant med teknikerna skulle jag förvänta mig att stöta på en del oväntade utmaningar.

I takt med att LLM:er blir mer avancerade och specialiserade versioner utvecklas kommer kvaliteten på svaren att förbättras avsevärt. AI kommer att snabba upp införandet av nya tekniker och processer inom DevOps.

Att uppnå en DevOps-grundnivå i praktiken med AI

Där har du alltså min demonstration av hur en DevOps-grundnivå kan uppnås i praktiken med hjälp av AI. Du behöver inga avancerade kunskaper för att komma i gång med prompting, men precis som i vilken sport som helst får du bättre resultat med övning.

Det finns fortfarande flera saker att förbättra utifrån grundnivån, till exempel omfattande Continuous Integration, inklusive DevSecOps och IaC.

Med hjälp av AI blir det enklare att komma i gång med DevOps-ämnen. Det finns mycket bra material på internet, och det verkar vara väl integrerat i LLM:er. Det är dock viktigt att förstå att designdiskussioner av det här slaget fungerar bättre med de mest avancerade LLM:erna. Samma diskussion med exempelvis GPT-3.5 skulle bli mycket annorlunda.

Ofta anses CI/CD vara en alltför stor investering för mindre projekt. Men investeringen uppväger lätt de kostnader som annars skulle uppstå om CI/CD försummas eller införs i ett senare skede. Det bör inte längre finnas någon anledning att tveka inför att investera i DevOps från början.

Med tiden förväntar jag mig att allt mer omfattande utvecklingsplattformar växer fram, där många processer automatiseras och utveckling samt DevOps blir mer abstrakta. Problemlösningsförmåga och en djup förståelse för de underliggande principerna kommer ändå att fortsätta vara viktiga.

Jag hoppas att det här blogginlägget har inspirerat dig att implementera DevOps från början och/eller förbättra din nuvarande situation.

Om du gillade det här blogginlägget kanske du även uppskattar vårt podcastavsnitt om AI i DevOps toolchain.

  • Software development
  • DevOps
  • CI/CD

Subscribe to our newsletter