Pipelines...

Rene Krewinkel, docent Sittard
04-11-2019

TL;DR In de categorie #TechTalk:

Als developer zul je in de praktijk steeds meer te maken gaan krijgen met het CI/CD concept. Deze afkorting staat voor Continuous Integration / Continuous Delivery. Waarbij CI eigenlijk betekent dat je niet te lang moet wachten voordat je je sources in het Version Control System (VCS) incheckt - dit om te voorkomen dat er teveel wijzigingen door het team in één keer verwerkt moeten worden waardoor de situatie kan ontstaan dat de wijzigingen die door de één zijn opgelost door de ander te niet worden gedaan. Een fenomeen dat bekend staat als “Merge Hell”.

Door de afspraken die je binnen je team maakt over de frequentie van de commits en de pushes naar de centrale repository, kun je dit voor een groot deel voor blijven. In principe zou je vóór je commit nog de unit-tests moeten/kunnen draaien om te voorkomen dat er foute code gedistribueerd wordt. 

Maar ja, daar waar afspraken gemaakt worden over de werkwijze, kun je er donder op zeggen dat dat ook wel eens mis gaat. Zaak dus om dat vergaand te automatiseren. 

Binnen CI/CD (en in de DevOps wereld in het algemeen) wordt hiervoor het begrip “pipeline” gehanteerd. Zo’n pipeline beschrijft de handelingen die verricht moeten worden om er voor te zorgen dat een applicatie zo stabiel mogelijk de wereld in geslingerd wordt - hetzij als “release”, hetzij als nieuwe branch voor het development team.

Continuous Deployment gaat nog een stapje verder en zorgt ervoor dat elke (geslaagde) build ook automatisch naar de juiste omgeving gepusht wordt. Veelal zijn de 2 onlosmakelijk met elkaar verbonden. 

Er zijn uiteraard hele websites en boeken volgeschreven met “best practices” omtrent dit principe, maar over het algemeen komt het - op hoofdlijnen - neer op de volgende workflow:

  1. Hanteer een VCS (Github, BitBucket, GitLab, SourceSafe, ….).
  2. Regelmatige (dagelijkse) commit
  3. Geautomatiseerde “builds” 
  4. Geautomatiseerde unit-tests en integratie tests
  5. Geautomatiseerd uitrollen naar test- en acceptatie- (en mogelijk zelfs productie-) omgevingen

Schematisch ziet dat er in een “pipeline” als volgt uit: 

Er is inmiddels tal van tooling beschikbaar om CI/CD “te plegen”, GitLab en BitBucket hebben ze zelfs geïntegreerd in hun platform - al dan niet tegen betaling. Een andere populaire tool is Jenkins, een zeer uitgebreid platform waarbij je tal van stappen in je pipeline kunt configureren. Het voor/nadeel van Jenkins is, is dat je de pipeline in het systeem moet configureren. 

Zelf gebruik ik Drone voor mijn projecten, een open-source tooling die je tegen betaling in een cloud omgeving kunt gebruiken, of via Docker gratis op je eigen server kunt draaien. Het grote voordeel van Drone (overigens heeft GitLab dezelfde functionaliteit, ook deels gratis) is het “pipeline as code”-concept. Oftewel: de hele configuratie van je pipeline zit als configuratie bestandje in je project opgenomen. De drone-server interpreteert dit bestandje en voert de stappen uit die erin beschreven staan.

Elke “step” binnen de drone pipeline installeert een (Debian Linux) docker container die na de stap weer netjes verwijderd wordt. Omdat deze file deel uitmaakt van je project, kun je deze dus ook gewoon naar behoefte wijzigen - niet altijd even handig natuurlijk, maar naarmate het project vordert moeten er misschien nieuwe stappen in het proces geïntroduceerd worden. 

Hieronder staat de “gist” van deze pipeline. Dit is een React frontend applicatie. Deze pipeline wordt door automatisch via een webhook door GitHub op mijn VPS gestart. 

Allereerst wordt de GitHub repository op de server in een Docker container gekloond. Vervolgens wordt in de eerste stap (build) eerst alle node modules geladen (regel 9), en vervolgens wordt een productie build gemaakt (regel 10). 

Als dit goed verlopen is - dit wordt in stap 2 op regel 14,15 en 16 vooraf gecontroleerd - wordt stap 2 (deploy) afgevuurd, deze installeert eerst ssh en sshpass in de container, (regel 21 en 22), haalt het admin wachtwoord op uit de configuratie (regel 17,18 en 19) en kopieert via scp de build naar - in dit geval - de acceptatie server. 

Stap 3 (notify) gaat altijd af (controle op regels 28 t/m 31) en haalt de Slack webhook op uit de configuratie en stuurt een push bericht in Slack of de build wel of niet gelukt is. 

Drone biedt je voor elke stap realtime output, en een rapport dat je achteraf kunt inzien:

Zo zie je dat het hele proces van inchecken tot en met uitrollen volledig geautomatiseerd is. Dat heeft zo z’n voordelen - vooral met development omgevingen als Symfony, Laravel en de diverse Node JS frameworks en libraries - aangezien je altijd met een heleboel bestanden en configuratie instellingen en dergelijke van doen hebt. Hoe vaak ben je niet een bestandje vergeten over te zetten of heb je de verkeerde connect string voor de database gebruikt?

Door een CI/CD pipeline in te richten voor je project kun je het leven een stuk aangenamer maken…

 Voor meer info of een demo, neem gerust even contact met me op!