Weblogs

Ontwikkelen van gedeelde Ansible rollen voor een Cloud Native Overheid

Tim Kok is Tech consultant bij het Rijks ICT Gilde en vervult de rol van DevOps Engineer bij ODC-Noord in Groningen. Vanuit zijn kennis en interesse op het gebied van cloud native technologieën en de architectuur van cloud applicaties, schreef hij een blog over het delen van code in het kader van Cloud Native Overheid: een samenwerkingsverband tussen rijksorganisaties die werken met Kubernetes en containertechnologie.

Een goede software engineer is een beetje lui. We vinden het niet leuk om dezelfde taken handmatig te doen en proberen problemen zo efficiënt mogelijk op te lossen. Deze mentaliteit zie je terug in de software die we schrijven, denk maar aan de principes "Don't repeat yourself" en nog belangrijker "Don't repeat others".

Om niet opnieuw het wiel uit te hoeven vinden, gebruiken we graag frameworks en libraries die ontwikkeld zijn door anderen. Hierdoor kunnen we ons richten op de unieke aspecten van ons probleem. Het is natuurlijk wel een vereiste dat iemand de moeite neemt om deze frameworks en libraries te ontwikkelen en beschikbaar te maken. Bij ODC-Noord werken we momenteel aan een opzet om Ansible rollen te delen in het kader van Cloud Native Overheid, samen met het Standaard Platform en Logius. In dit blog beschrijf ik een aantal factoren die belangrijk zijn om je code te delen met meerdere teams en organisaties.

Cloud Native Overheid

Cloud Native Overheid is een initiatief van een aantal rijksorganisaties, waaronder het Standaard Platform, Logius en ODC-Noord, om samen te werken op het gebied van Kubernetes en containers. Omdat we werken met dezelfde technologieën, is het nuttig om kennis en software met elkaar uit te wisselen.

Het Standaard Platform en Logius hebben bijvoorbeeld een aantal Ansible rollen ontwikkeld die wij bij ODC-Noord graag willen gebruiken binnen ons Kubernetesplatform. In plaats van de code te knippen, plakken en te integreren in de rest van onze codebase, willen we de rollen zo aanpassen dat alle partijen dezelfde code kunnen gebruiken en de rollen in de toekomst ook eenvoudig door andere organisaties gebruikt kunnen worden. Het voordeel is dat we met deze opzet het ontwikkel- en beheerwerk van de rollen in de toekomst kunnen delen, maar hiervoor moeten we vooraf een aantal zaken regelen.

Ansible, Ansible rollen en Ansible Galaxy

Ansible is een configuratieframework geschreven in Python. Het is een van de DevOps-tools om infrastructure as code mee te realiseren. Een van de componenten die je in Ansible gebruikt zijn rollen. Dit zijn herbruikbare stukjes code waarmee je specifieke functionaliteit uitrolt. Je kunt bijvoorbeeld rollen hebben om een VM op te spinnen in de cloud of Prometheus te installeren in een Kubernetes cluster. De package manager voor Ansible is Ansible Galaxy. Voor de gedeelde setup hebben we ervoor gekozen om de losse rollen te hosten in aparte git repo's en deze door middel van "ansible galaxy install" te installeren.

Modulaire code

Modulariteit en isolatie zijn sowieso eigenschappen van goede software, maar je kunt er niet omheen als de software gedeeld moet kunnen worden. Met andere woorden, de code van een Ansible rol moet een opzichzelfstaand pakketje zijn. Er zijn twee type afhankelijkheden waar je rekening mee moet houden: codetechnische afhankelijkheden en functionele afhankelijkheden.

Een voorbeeld van een afhankelijkheid in de code van de rollen is een common library met utility functies die op meerdere plekken in de codebase gebruikt worden. Zo'n library is natuurlijk een uitstekend voorbeeld van DRY en superhandig. Als oplossing hebben we deze code in een aparte repo gezet, zodat dezelfde common library door middel van dependencies kan worden geïmporteerd per rol. Andere code die op meerdere plekken in de codebase wordt gebruikt, kan worden toegevoegd aan deze common library. Door de common library te versioneren is deze afhankelijkheid ook beter beheersbaar. De rollen kunnen namelijk een specifieke versie van de library importeren en nieuwe versies kunnen per rol geïntroduceerd worden.

Andere afhankelijkheden zijn functioneel van aard. In de rollen wordt bijvoorbeeld uitgegaan van een clusterinrichting waarin is gekozen voor een specifieke identity provider (Keycloak), een specifieke ingress controller (Nginx) en een specifieke backup tool (Velero). Het voordeel van deze "opinionated" rollen is dat ze samen een geïntegreerd platform vormen, waarin van alles voor je is geregeld. Net zoals in veel webframeworks wordt hier gekozen voor "convention over configuration". Het is mogelijk om sommige integraties tussen componenten optioneel te maken (bijv. geen koppeling met een identity provider) of uit te breiden met meerdere smaakjes (bijv. ondersteuning voor andere identity providers). Dit zijn aanpassingen die codetechnisch redelijk eenvoudig te realiseren zijn, maar een grotere impact hebben op de architectuur.

Afspraken over de API en code style

Technisch is alles mogelijk, maar zoals elke software engineer weet, kost het tijd en moeite om de standaarden en conventies van een project met elkaar af te stemmen. Zeker als de samenwerking over meerdere teams en organisaties heen gaat, moet je duidelijke afspraken maken over de API en code style van de software. Op die manier is het voor iedereen duidelijk hoe een rol gebruikt kan worden, hoe wijzigingen aan de code van een rol eruit moeten zien en hoe een nieuwe rol opgezet moet worden.

In Ansible gebruik je variabelen om rollen aan te sturen en deze variabelen zijn dan ook je API. De structuur van deze variabelen moet in elke rol hetzelfde zijn, zodat bijvoorbeeld het opgeven van de naam van je Kubernetes cluster altijd op dezelfde manier gebeurt. Evenzo wil je dat de stijl van de code er hetzelfde uitziet in elke rol.

Documentatie

Documentatie schrijven we voor toekomstige gebruikers van onze code (waar wij zelf ook bij horen). Binnen een team kunnen collega's elkaar nog vragen stellen over de codebase als de documentatie gebrekkig is, maar als de toekomstige gebruikers geen contact met je kunnen opnemen dan wordt het lastig. Ook als ze wel je contactgegevens hebben, wil je waarschijnlijk het merendeel van de vragen afvangen met goede documentatie.

In de documentatie van een rol moet bijvoorbeeld staan welke configuratieopties er zijn, welke vereisten de rol heeft (bijv. toegang tot de kubectl client en een kubeconfig) en een voorbeeld van hoe de rol kan worden aangeroepen.

Testen

Om ervoor te zorgen dat alle partijen kunnen vertrouwen op de code, moet worden aangetoond dat een Ansible rol en wijzigingen aan de rol werken voor de verschillende platforms. Aan elke rol moet daarom een testsuite worden toegevoegd die alle configuratiemogelijkheden dekt en ook bijvoorbeeld rekening houdt met verschillen tussen Kubernetes distributies. Dankzij deze testsuites kunnen er niet onopgemerkt breaking changes worden geïntroduceerd. Zoals gebruikelijk in softwareontwikkeling, moeten er nieuwe testen worden geschreven, als de functionaliteit van een component wordt uitgebreid. Uiteindelijk is het doel om per rol een Continuous Integration pipeline op te zetten met een teststraat die garandeert dat een merge request de huidige functionaliteit voor iedereen intact laat.

Open/Community source structuur

In eerste instantie worden deze rollen gedeeld binnen de community van cloud native overheidspartijen. Het uiteindelijke doel is om de rollen als opensourceproject publiekelijk beschikbaar te maken. Hiervoor moeten een aantal vragen worden beantwoord: Wie is de eigenaar van de code? Wie mag merge requests indienen en wie mag ze goedkeuren? Hoe kunnen gebruikers bugs en feature requests indienen? Hoe zien de processen rondom release management eruit? Welke opensourcelicentie wordt er gebruikt? Dit zijn geen makkelijke vragen en gelukkig hoeven ze niet allemaal beantwoord te worden om te beginnen met het delen van code.

Conclusie

Hoewel de eerste rollen al succesvol zijn gedeeld, staat het delen en samen ontwikkelen van deze rollen nog in de kinderschoenen. Waarschijnlijk zullen er in de toekomst nog een paar factoren bij komen. Wat opvalt is dat veel van de best practices in softwareontwikkeling ervoor zorgen dat je makkelijker je software kunt delen. Denk aan goede documentatie, heldere API-afspraken en modulaire code. De andere groep factoren hebben betrekking op de afspraken tussen teams en organisaties. Aangezien deze factoren de basis vormen van de samenwerking is het belangrijk om die niet uit het oog te verliezen. Wordt vervolgd.

Tim Kok
Tim Kok

Tim Kok is DevOps Engineer bij ODC-Noord in Groningen. Hij heeft een achtergrond in filosofie en politicologie, maar uiteindelijk is hij in de IT beland als Fullstack Developer. Zijn interesses liggen in de ontwikkelingen van cloud native technologieën zoals Kubernetes, en de architectuur van cloud applicaties. Om zijn kennis op dit gebied te delen, heeft hij een blog geschreven over het delen van code in het kader van Cloud Native Overheid.

Reactie toevoegen

U kunt hier een reactie plaatsen. Ongepaste reacties worden niet geplaatst. Uw reactie mag maximaal 2000 karakters tellen.

* verplichte velden

Uw reactie mag maximaal 2000 karakters lang zijn.

Reacties

Er zijn nu geen reacties gepubliceerd.