Om een goed beeld te geven hoe wij DevOps aspecten toepassen binnen het Cloud Development Team hebben we onze DevOps Engineer, Jeroen Schouten, gevraagd om een blogreeks te schrijven. In deze serie blogs zullen wij alle aspecten beschrijven die binnen het DevOps spectrum passen.

In deel twee van deze reeks zoomen we in op de Release & Deploy fases van de DevOps lifecycle. In deel 1 lichtte ik toe hoe we bij DIJ de Build en Test fases hanteren. Een van de doelen van DevOps is om een korte ontwikkel lifecycle te hanteren waarbij feature, bugfixes en updates met regelmaat opgeleverd kunnen worden.

Die lifecycle bestaat uit ontwikkelen, testen, deployen en operationeel zijn. Zoals in deel 1 benoemd, maken we bij DIJ gebruik van Bitbucket Pipelines om het gros van onze applicaties in de DevOps lifecycle te krijgen. In blog 1: Build en Test fases gaf ik een voorbeeld build die wij hanteren. Dergelijke Pull Request builds voeren wij uit bij elke wijziging die een developer wil doen.

Voor de fase van Release en het uiteindelijke Deployen gebruiken we echter een Branch build die automatisch wordt uitgevoerd zodra er een wijziging is gemerged. Dit kan bijvoorbeeld een feature zijn die naar develop is gemerged, waarna op develop de build gaat lopen die naar de testomgeving gedeployed kan worden.

We maken hierbij gebruik van OTAP (ontwikkel, Test, Acceptatie, en Productie), waarbij de develop branch de testomgeving representeert, de acceptance branch de acceptatie omgeving, en de master branch de productie omgeving.

Elk van die branch builds maakt een artifact, in ons geval vaak een zip file, waarin onder andere de frontend assets (css, js, etc) gecompiled zijn en de noodzakelijke dependencies zijn geïnstalleerd (Composer). Ook secrets worden op een beveiligde manier op dit moment in de lifecycle in de applicatie gezet.

Het artifact sturen we samen met Laravel Envoy vanuit Bitbucket Pipelines naar de betreffende server(s) middels een beveiligde verbinding. Dit gebeurd automatisch tijdens deze branch build; het is een auto-deploy.

Hierbij maken we op de server gebruik van een releases map, een shared map en een current symlink. De symlink switchen we aan het eind van de deploy en zorgt voor zero downtime deployment (ook wel atomic deployment genoemd). Eventuele oudere releases blijven beschikbaar op de server zodat er in geval van nood snel een rollback gedaan kan worden.  In de shared map staan logs, uploads en dergelijke zodat die tussen deployments niet verloren gaan.

Omdat we meer en meer gebruik maken van cloud-based technologie is dit ook van invloed van de manier waarop we releasen en deployen. Applicaties zijn containerized met behulp van Docker en kunnen draaien op elke omgeving en hardware; van development machines tot productie-omgevingen in de AWS cloud. Met behulp van AWS CDK en Infrastructure as Code (blog) rollen we vanuit ons CI/CD proces de applicatie uit.

Dit is hoe we bij DIJ in een notendop deployen en releasen! Natuurlijk is elke applicatie maatwerk en zorgen we dat het releasen en deployen altijd feilloos werkt. Komen we iets tegen wat beter kan, dan pakken we dat meteen aan. Zo worden we elke dag een beetje beter!

In de volgende blogpost neem ik je mee in de Operatie en Monitor delen.

Geschreven door: Jeroen Schouten