Projectopgave CI/CD
Voorbereiding
Deze opgave wordt individueel afgewerkt...
Leerdoelen
- Begrip van het concept CI/CD
- Opzetten van CI/CD met behulp van GitLab en GitLab-runners
- Introductie in de 'devops'-filosofie
- Automatiseren en opzetten van pipelines met o.a. testen, staging en deployen van een complexere applicatie op basis van frontend-, backend- en databank componenten.
Opgave
Concept
Bouw een pipeline in GitLab die de Django applicatie uit het Docker project met behulp van CI/CD gaat deployen op een private cloud. Dat gebeurt in een staging-omgeving én in een productie-omgeving.
De uiteindelijke bedoeling is dat je na een merge request naar de staging of de production branch van de app-repo een pipeline zal triggeren die een reeks testen zal doorlopen en nieuwe container images zal bouwen voor frontend en backend.
Die containers komen dan in de GitLab container registry terecht als frontend-staging en backend-staging of frontend-production en backend-production.
Die container images worden bij een volgende stage van de pipeline gepusht naar de Kubernetes namespaces waar ze moeten gehost worden.
Eens die pipeline werkt voor staging, ga je aan de slag met productie. Dat is (uiteraard) in bijna alle opzichten een kopie van staging.
Voor dit project zal je veel kunnen recupereren van je twee eerste projecten. Daarom is het belangrijk dat je die keurig in GIT hebt gestopt. Maak wel een kloon van je Docker-repository om verder te gaan. Geef die een gestructureerde naam: 2526-IaC_CICD_Project-Familienaam Voornaam. Omdat we dezelfde machines en dus ook Controlhost gebruiken, cloon je deze nieuwe repo in een specifieke map op deze host. De repo voor Docker laat je voor wat hij is.
In deze opgave hoef je niet noodzakelijk altijd de volgorde van de taken te volgen. Als je op een bepaald punt geen antwoord meer kan vinden, kan je dus opteren om een ander stuk te proberen tot een goed einde te brengen.
Prerequisites
Voor dit project kan je gebruik maken van de machines die je eerder gebruikte op studentcloud.ikdoeict.be voor de opgave rond Docker.
Custom runner installeren en configureren
Voeg een custom runner toe aan Gitlab (in de eigen cloud-omgeving, we gaan deze omwille van efficientie ook plaatsen op de controlhost machine). Die moet voorzien worden van een tag, zodat je aan je CICD pipeline kan aangeven dat net deze runner moet gebruikt worden.
Als runner type kies je voor Docker.
Misschien zal je de runner config zo moeten instellen dat de containers elevated rechten hebben. Dat doe je door privileged = true op te nemen in de config.toml configuratie van de Gitlab-runner. In diezelfde configuratie kan je overigens ook een ‘parallel’ parameter instellen, waarmee je meerdere jobs gelijktijdig kan uitvoeren. Stel die in op 3.
Staging pipeline

Lint stage
In de app-repo staat de hele code (frontend en backend), en moeten minstens enkele branches aanwezig zijn: staging en main. Maak eventuele ontbrekende branches aan.
In deze repo zal de Gitlab ci/cd code in principe op elke branch identiek zijn. Als bepaalde jobs enkel moeten uitgevoerd worden in bepaalde branches, dan geef je dat uiteraard aan in een if-clausule.
Start met je CI/CD pipeline in de code-repo door het bouwen van de lint-stage. In deze stage maak je 1 job aan die Pylint, ruff of een andere linter voor Python uitvoert in de Django-applicatie. Exporteer zeker ook een gl-code-quality-report.json zodat dit opgepikt wordt in de Gitlab-interface.
Als je dat op de juiste manier doet (zie documentatie: https://docs.gitlab.com/ee/ci/testing/unit_test_report_examples.html), dan zullen de resultaten ook gelinkt worden aan een pipeline.

Bouwen van de build stage
Als de test-stage goed doorlopen wordt, dan mogen in de release stage de Docker images aangemaakt worden. In dezelfde stap worden de nieuwe containers ook naar de Gitlab container registry gepusht. Geef deze een tag zodat die kan gekoppeld worden aan de doorlopen pipeline. Als deze stap in de pipeline gelukt is in de staging-branch, zal je dus twee containers vinden in de Gitlab container registry: api-staging en frontend. De namen en tags kies je zelf, dit zijn slechts voorbeelden.
Bouwen van de test stage
We voeren in deze stage enkele testen uit die reeds vanuit GitLab aangeleverd worden. We voegen er vijf toe, maar dat zou heel makkelijk moeten zijn... Check de Gitlab-documentatie!
Bouw de deploy-stage
De kers op de taart is dat je container nu ook gedeployd wordt naar Kubernetes. Als je dat al werkend kreeg in het Docker-lab kan je daarvan profiteren, want eigenlijk hebben we bijna alle ingredienten om dit mogelijk te maken.
Je zal in deze stage met enkele commando's de containers vervangen op K8S. Voor de commando's kan je inspiratie opdoen uit volgend fragment. Het is uiteraard erg waarschijnlijk dat je het nog wat moet aanpassen voor jouw specifieke situatie.
script:
- kubectl set image deployment/backend-api
backend-api=$CI_REGISTRY_IMAGE/django-rest:$CI_COMMIT_SHORT_SHA
-n staging
- kubectl set image deployment/frontend-vue
frontend-vue=$CI_REGISTRY_IMAGE/frontend:$CI_COMMIT_SHORT_SHA
-n staging
- kubectl rollout status deployment/backend-api -n staging --timeout=120s
- kubectl rollout status deployment/frontend-vue -n staging --timeout=120s
Controle van je werk tot nu toe
Test en debug bovenstaande pipeline. Als alles goed loopt, wordt de applicatie getest, worden containers gebouwd en naar de artifact registry gestuurd, waarna de containers gedeployed worden naar de staging-omgeving.
Je moet dan ook kunnen surfen naar de applicatie op K8S. (let op welke poort je gebruikt, dat hangt af van hoe je de applicatie koppelde. Vermopdelijk is poort 8000 gebruikt voor staging.)
Production deploy
De deploy bij productie is quasi identiek aan die van staging, dus kan nu snel gaan. Het is ook niet nodig om daarbij de code volledig terug te gaan testen, dus die stap kan uit de pipeline gehaald worden mocht die nog actief zijn. Bescherm de branch voor productie wel, zodat enkel vanuit de staging-branch code kan overgezet worden via een merge request.
Ansible
We hebben erg gefocust in dit project op het deployen via Kubernetes. De pipelines kunnen natuurlijk nog zoveel meer. Maak een aanvullende stage die via Ansible een OS-update uitvoert op je DB-host bij elke deploy.
Extra
Werk een notificatie uit. Bij elke build die faalt of slaagt moet je daarvan een melding krijgen in 1 app naar jouw keuze. (Slack, mail, Teams, ...)