Ga naar inhoud

Samenvatting van de beslissingen over de templatebibliotheek

De bibliotheek legt haar ontwerpbeslissingen vast als decision records, in het Markdown-formaat MADR. Deze pagina vat ze samen: het probleem, de keuze en de gevolgen. De volledige records, met alle opties en argumenten, staan in de repository van de bibliotheek. De beslissingen zijn genummerd; de status is accepted tenzij anders vermeld. Waar de huidige repository laat zien hoe een beslissing uitpakt, staat een regel In de repository.

# Beslissing Status
0000 Beslissingen vastleggen in MADR Accepted
0001 Repositorystructuur Accepted
0002 Gedeelde resources tijdens tests Accepted
0003 Compliancetests met Azure Policy Accepted
0004 Testtool voor Bicep: Pester Accepted
0005 Testtool voor Terraform: Terratest Accepted
0006 Versiebeheer: per module Accepted
0007 Forks van upstream modules voor dringende fixes Proposed (in de praktijk getest)
0008 Geparametriseerde policies Accepted

0000: Beslissingen vastleggen in MADR

Probleem. Beslissingen over architectuur, code en andere onderwerpen hebben een formaat en een structuur nodig. Opties. MADR 3.0.0, de template van Michael Nygard, de Y-statements van sustainable architectural decisions, andere templates, geen afspraak. Keuze. MADR 3.0.0. Het maakt impliciete aannames expliciet, legt elke beslissing gestructureerd vast, is slank, makkelijk te lezen en te onderhouden, en het project is levend. Gevolg. Elke beslissing heeft dezelfde vorm (context, drivers, opties, uitkomst, gevolgen), zodat een latere lezer de redenering kan volgen.

0001: Repositorystructuur

Probleem. De bibliotheek heeft een voorspelbare structuur nodig waarop automatisering kan vertrouwen. Drivers. Een eenvoudige structuur die automatisering ondersteunt. Groeperen per technologie (Bicep en Terraform). Keuze. De structuur van een Terraform-module, aangepast: mappen voor examples, modules, pipelines en tests, elk opgesplitst per technologie en per module. Gevolg. Een duidelijke indeling naar functionaliteit, technologie en module. De structuur is in een vroeg stadium makkelijk te wijzigen. Het Azure Verified Modules-project gebruikt een vergelijkbare conventie. Zie Repositorystructuur.

In de repository: de structuur is gegroeid met scripts/, iac_accelerator/ en utils/, naast de vier mappen van de beslissing.

0002: Gedeelde resources tijdens tests

Probleem. De meeste modules hebben dezelfde afhankelijkheden nodig (netwerk, workspace, Key Vault, storage). Die in elke test uitrollen maakt de tests traag. Opties. Gedeelde resources gebruiken, of alle afhankelijkheden per test uitrollen. Keuze. Gedeelde resources, eenmalig aangemaakt vanuit een dependencies-map, met hun gegevens als JSON doorgegeven aan de tests. Gevolgen. Korte tests, één plek om de afhankelijkheden te wijzigen, hergebruik door Terraform- en Bicep-tests, en de afhankelijkheden maken geen deel uit van wat de tests controleren. De prijs is meer complexiteit en geen autocomplete in de editor voor de gedeelde waarden. Zie Testen.

0003: Compliancetests met Azure Policy

Probleem. De templates moeten voldoen aan de baselines van het platform (CIS, de Microsoft cloud security benchmark, ISO 27001), en de bibliotheek heeft een manier nodig om dat te testen. Opties. Statische analyse van de code (Checkov, Tfsec, Trivy, Open Policy Agent, Terrascan), of de compliance van de uitgerolde resources testen met Azure Policy. Keuze. Azure Policy. Het is onafhankelijk van de taal, eenvoudig, en de policies zijn de enige bron van waarheid. Gevolgen. De bibliotheek hoeft geen eigen regels te onderhouden, en de test kon snel worden gebouwd. Testen duurt langer, omdat resources worden uitgerold en geëvalueerd. Statische analyse gaf false positives (bijvoorbeeld bij geneste modules en loops), ontbrekende controles en zwakke Bicep-ondersteuning, en kan later alsnog worden toegevoegd als de testtijd een probleem wordt. Zie Testen.

In de repository: elke test roept hetzelfde policy-controlescript aan. Per module wordt een korte lijst policies genegeerd, elk met een reden (Genegeerde policies, Bekende bevindingen).

0004: Testtool voor Bicep

Probleem. Elke template moet worden uitgerold en de resources moeten daarna worden verwijderd, met een zo laag mogelijke testtijd en weinig implementatie-inspanning. Opties. Pester, of een eigen PowerShell-loop met parallelle deployments. Keuze. Pester, met een script voor parallelle runs. Het kost weinig werk om de output vast te leggen en een rapport voor de pipeline te maken, en het geeft een standaard voor de tests van nieuwe modules. Gevolgen. De totale testtijd in het rapport klopt niet, en het log toont de output pas als alle tests klaar zijn.

In de repository: een runnerscript start per testbestand één thread job en voegt de resultaten samen in één JUnit-rapport.

0005: Testtool voor Terraform

Probleem. Hetzelfde als voor Bicep, maar dan voor Terraform. Opties. Terratest, of de native terraform test. Keuze. Terratest. Beproefd en volwassen, flexibel, en het draait tests parallel. Gevolgen. Parallelle tests (de CI-pipeline draait er maximaal tien tegelijk), en de tool kan later voor andere soorten tests worden gebruikt. Er is wat kennis van Go nodig om de eerste structuur op te zetten. terraform test was eenvoudig en native, maar heeft geen parallellisme, minder flexibiliteit en minder volwassenheid.

0006: Versiebeheerstrategie

Probleem. Afnemers moeten bewust kunnen beslissen wanneer ze upgraden, in plaats van altijd de nieuwste code te gebruiken. Opties. Eén versie voor de hele oplossing, één per technologie, of één per module. Keuze. Per module, met semantic versioning en git tags zoals bicep/storage_account/1.0.1, omdat de andere twee misleidende nummers geven. Gevolgen. Versienummers die de waarheid vertellen, ten koste van een complexer releaseproces. Uit een rondvraag bij andere repositories met gedeelde modules bleek dat monorepos meestal één versie per repository gebruiken, en dat niemand Terraform- en Bicep-modules in één product combineerde. Het team ziet de keuze als een experiment en verwacht ervan te leren. Zie Versiebeheer.

In de repository: tags hebben de vorm terraform/<module>/<version> en bicep/<module>/<version>, en het patchnummer wordt door het releasescript bepaald (Tags).

0007: Forks van upstream modules voor dringende fixes

Status. Proposed. Probleem. De modules roepen Azure Verified Modules aan, die kleine bugs hebben. Fixes wachten vaak maanden op review upstream, en een workaround is niet altijd mogelijk. De bibliotheek wil ook vergelijkbare Terraform- en providerversies over modules heen, wat bijdragen aan veel modules met verschillende eigenaren zou vereisen. Opties. AVM alleen als referentie gebruiken en de code kopiëren. Bijdragen aan AVM en wachten. AVM-repositories forken en onderhouden. Bijdragen aan AVM, en forks in de bibliotheek gebruiken wanneer de review te lang duurt (een mix). Keuze. De mix: upstream bijdragen, en een fork van de module vanuit de bibliotheek aanroepen wanneer de review te lang duurt of een dringend incident het vereist. Het team wil dicht bij AVM blijven en waarde teruggeven, in plaats van de modules volledig zelf te onderhouden. Gevolgen. De bibliotheek blijft AVM gebruiken, geeft waarde terug en kan een snelle fix leveren. Een complete wijziging kost meer tijd en moeite, en het bijwerken van de aangeroepen AVM-versie blijft werk. Het team test of dit in de praktijk werkt. Zie Bugs in upstream modules.

In de repository: de Terraform-module voor container instances roept een fork van de AVM-module aan, en de Terraform-module voor container apps is niet langer een wrapper om een andere module maar bezit zijn eigen resourcelogica (Modulecatalogus).

0008: Geparametriseerde policies

Probleem. De modules leggen de waarden vast die een policy controleert, zodat gebruikers geen niet-compliant resources kunnen uitrollen. Sommige policies hebben parameters die elk platform anders instelt, en sommige hebben geen standaardwaarde. Opties. De standaardwaarde als constante gebruiken, en een input variable gebruiken als er geen standaardwaarde is. Altijd een input variable gebruiken. Alleen de gevallen documenteren die niet vast te leggen zijn. Of de eerste optie plus documentatie van de gevallen waarin een constante nodig is. Keuze. De standaardwaarde van de parameter als constante in de module. Als de policy geen standaardwaarde heeft, een input variable. Alle gevallen waarin de waarde niet kan worden afgedwongen, worden gedocumenteerd. Gevolgen. De modules zijn zo veilig als de standaarden vereisen. Ze passen in minder situaties, dus een team moet voor een bijzonder geval mogelijk een kopie van een module maken, met extra werk. Zie Geparametriseerde policies.

In de repository: de vaste waarden zijn te zien in de locals.tf van een module (Policy compliance).