IaC en CI/CD best practices combineren met low code?

Case
17 November 2023

Joost van Dam

Hoe we een internationaal SaaS-platform deployen met behulp van low code, IaC en CI/CD best practices.

In één van mijn vorige blog posts sprak ik over het inzetten van Azure Function Apps via Custom connectors om de functionaliteiten van het Power Platform gemakkelijk uit te breiden. Recent hebben we echter nieuwe situaties ontdekt waarin het omgekeerde ook waar bleek te zijn! Ik wil je dan ook graag laten zien hoe we low code, IaC en CI/CD best practices inzetten om een internationaal SaaS-platform op het gebied van voedselveiligheid te deployen wat we momenteel bouwen voor een opdrachtgever.

Side note: ben je benieuwd welk SaaS-platform dat is? Houd dan onze communicatiekanalen in de gaten, want binnenkort gaat dit platform live.

Hoewel het een complex proces betreft, zal ik proberen om de relevante technische concepten en afwegingen zo goed mogelijk hieronder toe te lichten.

De uitdaging

Er komt wel wat kijken qua deployment bij de ontwikkeling van een groter SaaS-platform wat tegelijkertijd gebruikt én doorontwikkeld wordt. We moeten ervoor zorgen het platform modulair kan worden uitgebreid en dat elke nieuwe versie minstens zo goed functioneert als de vorige. In dit project hebben we te maken met diverse apps en tal van omliggende services die in wisselende samenstelling moeten communiceren. Ook wijzigen de benodigde (Azure) cloud resources waar de code gebruik van maakt tussen de verschillende releases (nieuwe versie van het platform).

Hoe hebben we dit deploymentproces betrouwbaar ingericht?

Code → Build. Build + Config → Release.

Allereerst passen we binnen Shared de Twelve-Factor App-methodologie toe. Hieruit volgt onder andere dat source code leidt tot een build. Vervolgens leidt deze build aangevuld met een configuratie-bestand tot een release.

Het ontbrekende stuk is de infrastructuur (Azure cloud services). De release moet natuurlijk ook ergens draaien, en is waarschijnlijk afhankelijk van extra services (Databases, app-registraties, …). Hiervoor gebruiken we Infrastructure as Code (IaC), waarmee je op basis van code de benodigde infrastructuur kunt definiëren en in één keer kunt laten neerzetten door de cloud provider (Microsoft Azure). In ons geval maken we gebruik van Bicep en een in-house ontwikkelde Command Line Interface (CLI), wat voor deze toepassing de beste resultaten biedt binnen Microsoft Azure en Microsoft Entra ID.

Versiebeheer in de praktijk

In theorie kunnen we dus alle onderdelen van het SaaS-platform in code en configuratie vatten, waardoor er ook versiebeheer van deze bestanden mogelijk is. Maar hoe werkt dat versiebeheer in de praktijk?

De uitdaging ligt er allereerst in om source code (builds), configuratie en IaC op te kunnen slaan als statische bestanden waarover versiebeheer gevoerd kan worden. Dit hele proces wordt uitgevoerd binnen Github Actions, waarin onder andere de source code wordt omgezet in builds, het volledige pakket geautomatiseerd wordt getest en – indien succesvol – de verschillende onderdelen opslaat binnen Microsoft Azure.

Builds
In de eerste plaats de builds. We doen dit voor de statische onderdelen (bijv. Single Page Applications en Function Apps) in de vorm van ZIP-bestanden en voor de ingewikkelder services gebruiken we Docker images die geüpload worden naar een Azure Container Registry.

Configuratie
In de tweede plaats de configuratie. Die is vrij simpel en bestaat uit JSON-bestanden die ook prima in een Azure Blob Storage container opgeslagen kunnen worden.

Infrastructuur
Tenslotte infrastructuur. Dit was iets lastiger omdat alleen de inzet van Bicep niet voldoende was. Er waren aanvullend meerdere scripts nodig om onder andere B2C-Tenants te configureren. Dit hebben we opgelost door het hele script (B2C-Tenants, Bicep, etc.) óók in een Docker image te verpakken. Op deze manier kunnen we ook hiervan verschillende ‘versies’ opslaan.

Briljant! We kunnen nu onbeperkt verschillende versies van de drie hoofdingrediënten (build, configuratie en infrastructuur) opslaan en op deze manier verschillende releases samenstellen en deployen. Nu we deze IaC en CI/CD best practices hebben staan rest de vraag: hoe houden we alles bij?

Bijhouden van versies en releases

Om het samengestelde pakket van build, configuratie en infrastructuur als één geheel neer te kunnen zetten in een test-, acceptatie of productie-omgeving, komen we bij het sluitstuk van dit deploymentproces. Allereerst wordt er aan het einde van de pipeline in Github Actions een release configuratie-bestand gemaakt (in JSON-formaat, zie hieronder) met daarin de benodigde versies van de verschillende applicaties, configuratie en infrastructuur. Het mooie van dit systeem is dat we naar oudere versies kunnen verwijzen en er zodoende niks dubbel opgeslagen dient te worden.

Voorbeeld van de JSON-opbouw van een release

De individuele versies en de totale samenstelling van de release worden door middel van een Azure Function App bijgehouden in een Azure Blob Storage tabellen. De app biedt onder andere de volgende endpoints om:

  • nieuwe releases samen te stellen bestaande uit versies van builds, configuratie en infrastructuur;
  • een release naar een specifieke omgeving (bijv. acceptatie of productie) te deployen
  • historische deployments in te zien. Dit geeft bijvoorbeeld zicht op welke release in welke omgeving actief is.

Het is natuurlijk prachtig dat hiervoor een API beschikbaar is, maar dat maakt het beheer nog niet gebruiksvriendelijk. Hiervoor hebben we tenslotte de Power App nodig.

Het orkestreren van releases via een Power App

Nu we een API hebben voor het aanmaken van nieuwe releases en de deployment daarvan, biedt dit de mogelijkheid om snel een low code applicatie neer te zetten in Microsoft Power Apps om het deploymentproces te orkestreren. Alle complexe zaken vinden plaats achter de API en in Github Actions, waardoor een low code oplossing zich uitstekend leent om dit beheer op een gebruiksvriendelijke manier uit te voeren.

De Power App biedt de volgende functionaliteiten:

  • Direct starten of inplannen van deployments op basis van geselecteerde release en doelomgeving.
  • Oude releases herstellen.
  • Inzicht in huidige actieve releases binnen de DTAP-omgevingen.
  • Change log / audit feed van historische releases.
  • Goedkeuringsprocedure voor releases naar productie, bijvoorbeeld via testteam of product owners.
  • Notificaties naar gebruikersgroepen wanneer er een nieuwe release beschikbaar is, inclusief release notes.

Best goed toch?

Tot slot

Zo, nu heb je ruwweg een beeld van het deploymentproces van een SaaS-platform. Je zult zien dat ons huidige proces bij elk nieuw project steeds weer verder bijgeschaafd zal worden; we blijven natuurlijk continue leren!

Mocht het bovenstaande verhaal jou nou aanspreken en kom je graag in gesprek hoe je deze IaC en CI/CD best practices bijvoorbeeld zelf kunt toepassen? Neem dan vooral contact met ons op en wie weet spreken we elkaar hier binnenkort over. Lijkt me leuk!

Contact

Je naam
This field is for validation purposes and should be left unchanged.
Shared BV

Vasteland 12G
3011 BL Rotterdam

+085 833 0011 info@shared.nl
Sluiten