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).