Skip to main content

Projectopgave CI/CD

Voorbereiding

Deze opgave wordt individueel afgewerkt...

Leerdoelen

  • Begrip van het concept CI/CD
  • Opzetten van CI/CD adhv Gitlab en Gitlab-runners
  • Introductie in de 'devops'-filosofie
  • Automatiseren en opzetten van pipelines met oa. testen, staging, deployen van een complexere applicatie op basis van fontend-, backend- en databank componenten.

Opgave

Concept

Bouw een pipeline die de Django applicatie uit het Docker project met behulp van Gitlab 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 met een git push in 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 servers waar ze moeten gehost worden.

Eens die pipeline werkt voor staging, ga je aan de slag met productie. De verschillen tussen beide zijn niet zo groot. Bij staging wordt een Docker container gebruikt voor de databank, bij productie zal daarvoor een ‘echte’ mysql-server gebruikt worden voor optimale performance en makkelijker beheer.

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.

Prerequisites

Voor dit project kan je gebruik maken van de “OPO_IaC_CICD_Project”-deployment op cloud.ikdoeict.gent. 

Deze deployment maak je aan met volgende naam: “2324-IaC_CICD_Project_Familienaam_Voornaam”

Je zal ook twee repositories nodig hebben:

  • 2324-IaC_CICD_Project_Familienaam_Voornaam-app
  • 2324-IaC_CICD_Project_Familienaam_Voornaam-infra

Custom runner installeren en configureren

Voeg een custom runner toe aan Gitlab (in de eigen cloud-omgeving, op de pipeline-runner 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.

Als het nodig is om de pipeline runner VM te configureren (updates, installatie docker, ...), dan mag je dat manueel doen. Liefhebbers mogen zich uiteraard ook uitleven met Ansible...

tip

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.

Infra-pipeline

Bouw in de infra-repo (die verder leeg is) een CI/CD pipeline die de verschillende servers goed configureert. In de infra-repo vind je (minstens) de branches staging en production. Op basis van de branch waar je naar pusht zal de infra deployen bij de twee staging- of de twee productieservers. Binnen de pipeline kan je daarvoor de Ansible code (gedeeltelijk) gebruiken die je al eerder maakte.

Enkele zaken die minimaal moeten gebeuren:

  • Installeer binnen deze pipeline Docker op alle hosts waar dat nodig is.
  • Installeer MySQL op de production-db-host en maak een db aan, inclusief credentials om aan te melden.
  • Configureer de firewalls waar nodig.

Eens deze pipeline goed functioneert, is het vermoedelijk niet nodig om die nog vaak te runnen, tenzij er bijvoorbeeld een nieuwe server moet geconfigureerd worden.

Deze pipeline zal uiteraard moeten uitgevoerd worden op je eigen runner: die heeft toegang tot je omgeving..

Je kan hiervoor een voorgeconfigureerde Ansible container gebruiken, of er zelf eentje maken, dat kies je zelf.

warning

Variabelen en credentials stop je uiteraard niet in de repository. Configureer de nodige variabelen in Gitlab CI/CD.

Test dit door connecties te leggen naar de geconfigureerde server met de nieuwe mysql- gebruiker vanop je runner-vm.

tip

de MySQL-configuratie kan je ook aanpassen door de my.cnf config-file aan te passen of te overschrijven

Configureer in Gitlab CI/CD de variabelen die nodig zijn om Mysql te gebruiken als CI/CD variabelen. Jouw Django applicatie zal die omgevingsvariabelen gebruiken.

Let daarbij op dat de variabelen ook toegankelijk zijn vanaf unprotected branches en vanuit alle environments. 

Staging pipeline

Test stage

In de app-repo zet je de hele code (frontend en backend), en moeten minstens enkele branches aanwezig zijn: development, staging en production. Deze repo kan dus eigenlijk een kloon zijn van het resultaat van de Docker-project. De development-branch zullen we verder niet gebruiken voor deployments, maar even verder lees je wel dat er enkele testen op gebeuren.

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 test-stage. In de test-stage maak je 1 job aan die Pytest uitvoert in de Django-applicatie. 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 Pytest-resultaten ook gelinkt worden aan een pipeline. In de bron-repo op Gitlab zitten reeds enkele werkende unittests vervat.

Voeg ook een syntax-linter (Pylint) toe aan deze stage.

Deze testen moeten enkel in de development en staging-branch gebeuren.

(Op de frontend gebeuren geen testen, dat valt buiten de scope van de opgave.)

Bouwen van de release 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 front-staging. De namen en tags kies je zelf, dit zijn slechts voorbeelden. Voor de productie-branch zal je eveneens twee images hebben.

Bouw de deploy-stage

Dat is vermoedelijk de meest complexe stap. We zullen opnieuw gebruik maken van Ansible in de verschillende jobs. Met Ansible zal de staging-web server klaargemaakt worden voor- en gedeployed worden met de twee net gebouwde docker-images, voor front-end en backend.

Stappen in deze job:

  • Installeer Ansible in de container die je gebruikt voor deze job (of gebruik een klaargemaakte Ansible-mage)
  • Voer daarmee een Ansible script uit dat:
    • De images die gebuild werden (of in het geval van mysql misschien gewoon binnengehaald werd) zal deployen. Het gaat daarbij over frontend, mysql én backend. Die twee webcontainers komen op dezelfde host, de databank op een andere. Voor de databank kan je uiteraard gebruik maken van publieke images, die hoef je niet zelf te builden of te hosten.

Stuur alle environment variabelen mee zodat vb de databank-connectie opgezet kan worden.

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 de staging web-host. (let op welke poort je gebruikt, dat hangt af van hoe je de applicatie koppelde)

Production deploy

De deploy bij productie is quasi identiek aan die van staging, al wordt daar een echte databank gebruikt op de 'Prod DB'-host. 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.

Extra

Selecteer twee van onderstaande extra’s om uit te voeren: 

  • Voeg de security-testen toe die Docker voorziet voor het scannen van de containers. Voer ook een coverage-test uit in de staging-pipeline
  • Integreer SAST
  • integreer container scanning
  • Voeg ook een linter toe aan de Vue-code
  • Maak code coverage zichtbaar in de Gitlab interface. Pas daarvoor ook de test-stage aan.