Azure Monitor Configuratie: Architectuur, Implementatie En Governance

💼 Management Samenvatting

Azure Monitor-configuratie vormt de fundering van observability en compliance binnen elke moderne Azure-tenant. Een goed geconfigureerde Azure Monitor-omgeving biedt organisaties volledige zichtbaarheid op de gezondheid, prestaties en beveiliging van hun cloudinfrastructuur, applicaties en diensten. Zonder een doordachte configuratiestrategie ontstaat echter een gefragmenteerd monitoringlandschap waarin logdata inconsistent wordt verzameld, kritieke gebeurtenissen onopgemerkt blijven, compliance-vereisten niet worden nageleefd en kosten onbeheersbaar worden door overmatige data-inname.

Aanbeveling
IMPLEMENT
Risico zonder
High
Risk Score
9/10
Implementatie
36u (tech: 24u)
Van toepassing op:
Azure
Hybride omgevingen

Veel Nederlandse overheidsorganisaties hebben Azure Monitor geïmplementeerd, maar missen een gestructureerde configuratieaanpak die rekening houdt met governance, compliance en kostenbeheersing. In de praktijk zien we vaak dat Log Analytics workspaces ad-hoc worden aangemaakt zonder consistente naamgeving en tagging, dat diagnostische instellingen niet zijn geconfigureerd waardoor belangrijke logdata ontbreekt, dat retentie-instellingen niet zijn afgestemd op wettelijke bewaarplichten zoals vastgelegd in de Archiefwet en de BIO, en dat kostenbeheersing ontbreekt waardoor maandelijkse kosten onverwacht oplopen. Deze configuratiefouten leiden tot compliance-risico's, onnodige kosten, verminderde zichtbaarheid op beveiligingsincidenten en het onvermogen om richting bestuurders en auditors aan te tonen dat monitoring op orde is. Bovendien ontbreekt vaak een centraal overzicht van welke resources zijn geïnstrumenteerd, welke configuraties actief zijn en hoe monitoring wordt gebruikt voor incidentdetectie en service level management.

PowerShell Modules Vereist
Primary API: Azure Monitor
Connection: Connect-AzAccount
Required Modules: Az.Accounts, Az.Monitor, Az.OperationalInsights, Az.Resources

Implementatie

Dit artikel beschrijft een gestructureerde aanpak voor het configureren van Azure Monitor binnen de Nederlandse Baseline voor Veilige Cloud. We behandelen architectuurkeuzes zoals de inrichting van Log Analytics workspaces met juiste retentie-instellingen en data-exportmogelijkheden, configuratie van diagnostische instellingen voor platformlogs en metrische data, implementatie van Log Analytics agents voor hybride omgevingen, afstemming van retentie-instellingen op compliance-frameworks zoals de Archiefwet, BIO en ISO 27001, en inrichting van role-based access control voor scheiding van ontwikkel- en beheertaken. Daarnaast gaan we in op het beheer van Log Analytics workspaces via Infrastructure as Code, configuratie van data-export naar SIEM-systemen en externe opslag voor langetermijnbewaring, implementatie van kostenbeheersing door middel van data-cap en ingestiebeperkingen, en het opzetten van alertregels die aansluiten op bestaande incidentresponse-processen. Het artikel sluit af met governance-richtlijnen voor naamgeving, tagging, kostenbewaking en periodieke configuratiereviews, en toont hoe het bijbehorende PowerShell-script azure-monitor-configuration.ps1 kan worden gebruikt om de configuratie te monitoren, te valideren en waar nodig te herstellen.

Architectuur en Ontwerpprincipes voor Azure Monitor Configuratie

Een effectieve Azure Monitor-configuratie begint bij architectuurkeuzes die bepalen hoe telemetrie wordt verzameld, opgeslagen en geanalyseerd. De kern van Azure Monitor bestaat uit Log Analytics workspaces, die functioneren als centrale opslagplaatsen voor logdata, metrische gegevens en custom telemetrie. Voor Nederlandse overheidsorganisaties adviseren we een hiërarchische workspace-architectuur waarbij productie-, acceptatie- en ontwikkelomgevingen elk hun eigen workspace hebben, maar waarbij kritieke beveiligings- en auditlogs centraal worden verzameld in een dedicated security workspace. Deze scheiding maakt het mogelijk om retentie-instellingen per omgeving af te stemmen op compliance-vereisten: productielogs kunnen bijvoorbeeld zeven jaar worden bewaard voor auditdoeleinden, terwijl ontwikkellogs na negentig dagen kunnen worden verwijderd om kosten te besparen. Bovendien biedt deze architectuur betere mogelijkheden voor toegangscontrole omdat ontwikkelaars geen toegang hoeven te hebben tot productielogs met gevoelige gegevens. Een veelgemaakte fout is om voor elke resource of applicatie een aparte workspace aan te maken. Dit leidt tot gefragmenteerde monitoring, hogere kosten door duplicate data-inname en het onvermogen om correlaties te leggen tussen gebeurtenissen in verschillende workloads. Daarom is het verstandig om workspaces te groeperen op basis van organisatorische grenzen, compliance-vereisten en geografische locatie. Voor een middelgrote overheidsorganisatie kan dit bijvoorbeeld betekenen: één centrale workspace voor alle productie-Azure-resources, één workspace voor hybride servers en on-premises workloads, en één workspace voor security-specifieke logs die worden geëxporteerd naar een SIEM-systeem. Binnen elke workspace configureert u vervolgens tabellen met passende retentie-instellingen: auditlogs en security events kunnen lang worden bewaard, terwijl performance metrics en verbose application logs kortere retentieperioden krijgen. Naast workspace-architectuur is het cruciaal om diagnostische instellingen consistent te configureren voor alle kritieke Azure-resources. Diagnostische instellingen bepalen welke platformlogs en metrische data worden verzameld en waar deze naartoe worden gestuurd. Voor resources zoals Virtual Machines, Storage Accounts, Key Vaults en Azure AD moet u expliciet configureren dat auditlogs, security events en operationele logs worden doorgestuurd naar de juiste Log Analytics workspace. Zonder deze configuratie blijven belangrijke gebeurtenissen zoals mislukte authenticatiepogingen, wijzigingen in beveiligingsinstellingen en prestatieproblemen onzichtbaar, waardoor incidenten te laat worden gedetecteerd en compliance-vereisten niet worden nageleefd. Het PowerShell-script azure-monitor-configuration.ps1 sluit hierbij aan door te controleren of diagnostische instellingen aanwezig zijn op alle resources die als kritiek zijn gemarkeerd, en door te rapporteren welke resources nog niet correct zijn geïnstrumenteerd.

Implementatie en Automatisering van Azure Monitor Configuratie

Zodra de architectuur is bepaald, verschuift de aandacht naar een beheerbare implementatie. Voor een middelgrote tot grote overheidsorganisatie is het onhaalbaar om Azure Monitor-configuraties handmatig via de Azure Portal te onderhouden; wijzigingen in resources, nieuwe abonnementen of workloads zouden al snel leiden tot inconsistenties en vergeten configuraties. Daarom is het cruciaal om Azure Monitor-configuraties zoveel mogelijk als code te beheren, waarbij PowerShell, ARM/Bicep of Terraform de bron van waarheid vormen. Praktisch betekent dit dat u templates definieert voor Log Analytics workspaces met standaard retentie-instellingen, diagnostische instellingen voor veelvoorkomende resource types, en alertregels die aansluiten op bestaande incidentresponse-processen. PowerShell speelt hierbij een dubbele rol. Enerzijds gebruikt u scripts om op gecontroleerde wijze nieuwe Log Analytics workspaces aan te maken met de juiste configuratie, bijvoorbeeld op basis van een naming convention en standaard tags. Anderzijds gebruikt u scripts om de bestaande configuratie te inventariseren en af te zetten tegen de gewenste situatie. Het script azure-monitor-configuration.ps1 in deze baseline is specifiek ontworpen voor dat laatste. Het script maakt verbinding met Azure via Connect-AzAccount (of een vooraf geconfigureerde managed identity-context), leest alle abonnementen uit waarop de uitvoerende identiteit rechten heeft en verzamelt voor elk abonnement informatie over Log Analytics workspaces, diagnostische instellingen en agent-configuraties. Daarbij wordt onder andere vastgelegd: of workspaces correct zijn getagd, welke retentie-instellingen actief zijn, welke resources diagnostische instellingen hebben geconfigureerd, en of Log Analytics agents correct zijn geïnstalleerd op hybride servers. Op basis van deze data vergelijkt het script de gevonden configuraties met een set minimale vereisten die u in het script of in een begeleidend configuratiebestand vastlegt. Denk bijvoorbeeld aan de eis dat iedere productie-workspace een retentieperiode heeft van minimaal 365 dagen voor auditlogs, of de eis dat alle kritieke resources (gemarkeerd met tags zoals Critical=True) diagnostische instellingen hebben die logs naar een centrale workspace sturen. Voor resources waarvoor dergelijke configuraties ontbreken, markeert het script de situatie als non-compliant en voegt het een duidelijke toelichting toe aan de resultaten. Deze resultaten kunnen vervolgens worden geëxporteerd naar JSON of CSV en via dashboards worden gevisualiseerd, waardoor de CISO of cloudcompetencecenter inzicht krijgt in de daadwerkelijke status van de monitoring-inrichting. Hoewel dit script zich in eerste instantie richt op monitoring en compliance, kan het ook een startpunt zijn voor geautomatiseerde remediatie. Door de inventarisatiefase te combineren met aanmaak- of update-acties op workspaces en diagnostische instellingen, kunt u zorgen dat nieuwe of gewijzigde resources automatisch de juiste monitoring-configuratie krijgen. In de baseline is er bewust voor gekozen om remediatie in azure-monitor-configuration.ps1 beperkt en voorzichtig te houden: de functie Invoke-Remediation toont welke aanpassingen nodig zijn en kan – indien expliciet bevestigd – standaard-configuraties aanmaken op basis van vooraf gedefinieerde parameters. Voor productieomgevingen wordt aanbevolen om deze logica te combineren met Infrastructure as Code in CI/CD-pijplijnen, zodat wijzigingen aan monitoring-configuraties onderdeel worden van dezelfde change- en reviewprocessen als de onderliggende infrastructuur.

Gebruik PowerShell-script azure-monitor-configuration.ps1 (functie Invoke-Monitoring) – Voert een tenant-brede inventarisatie en compliancecheck uit op Azure Monitor-configuraties, inclusief Log Analytics workspaces, diagnostische instellingen en agent-configuraties..

Kostenbeheersing en Retentie-instellingen voor Compliance

Azure Monitor kan aanzienlijke kosten genereren wanneer logdata onbeperkt wordt verzameld zonder strategie voor kostenbeheersing. Voor Nederlandse overheidsorganisaties is het daarom essentieel om expliciete retentie-instellingen te configureren die balanceren tussen compliance-vereisten en kostenoptimalisatie. De Archiefwet vereist bijvoorbeeld dat bepaalde categorieën administratieve gegevens langdurig worden bewaard, terwijl de AVG stelt dat persoonsgegevens niet langer mogen worden bewaard dan noodzakelijk. Azure Monitor biedt flexibele mogelijkheden om deze tegenstrijdige eisen op te lossen door per tabel of per workspace verschillende retentieperioden te configureren. Voor auditlogs en security events die relevant zijn voor compliance-audits adviseren we een retentieperiode van minimaal 365 dagen, en voor kritieke beveiligingsgebeurtenissen zelfs zeven jaar conform de Archiefwet. Voor performance metrics en verbose application logs kan een kortere retentieperiode van 30 tot 90 dagen volstaan, omdat deze data primair wordt gebruikt voor operationele troubleshooting en niet voor langetermijn-auditdoeleinden. Daarnaast biedt Azure Monitor de mogelijkheid om data te exporteren naar externe opslag zoals Azure Blob Storage of een SIEM-systeem voor langetermijnbewaring, waardoor u kosten kunt besparen door korte retentie in Log Analytics te combineren met langetermijnopslag elders. Kostenbeheersing gaat verder dan alleen retentie-instellingen. Azure Monitor biedt verschillende mechanismen om data-inname te beperken, zoals data-cap instellingen die automatisch data-inname stoppen wanneer een maandelijks limiet wordt bereikt, en ingestiebeperkingen die voorkomen dat overmatige logging leidt tot onverwachte kosten. Voor productieomgevingen is het verstandig om data-cap in te stellen op basis van historische verbruikspatronen, maar wel met een buffer voor onverwachte pieken tijdens incidenten. Daarnaast kunt u kosten besparen door slimme sampling te configureren voor application telemetrie, waarbij alleen een representatieve steekproef van events wordt verzameld in plaats van alle gebeurtenissen. Het PowerShell-script kan hier input voor leveren door te rapporteren welke workspaces het meeste data verbruiken, welke tabellen de grootste volumes genereren en of data-cap instellingen actief zijn. Op basis van deze informatie kunt u gericht bijsturen door retentie-instellingen te verfijnen, onnodige diagnostische instellingen uit te schakelen en data-export te configureren voor langetermijnbewaring.

Governance, Compliance en Continue Verbetering

Gebruik PowerShell-script azure-monitor-configuration.ps1 (functie Invoke-Remediation) – Ondersteunt verbetering van de Azure Monitor-configuratie door niet-conforme resources te identificeren en – indien gewenst – standaard-configuraties voor kritieke workloads aan te maken..

Een Azure Monitor-configuratie is geen statisch ontwerp dat na implementatie kan worden vergeten. Nieuwe workloads, wijzigingen in architectuur, wijzigende compliance-vereisten en lessen uit incidenten vereisen dat monitoring-configuraties doorlopend worden geëvalueerd en aangepast. Zonder actieve governance ontstaan na verloop van tijd blinde vlekken: nieuwe abonnementen krijgen geen diagnostische instellingen, verouderde workspaces blijven actief zonder eigenaar, retentie-instellingen worden niet herzien waardoor compliance-risico's ontstaan, en kosten lopen op door overmatige data-inname. Daarom moet de inrichting van Azure Monitor ingebed worden in het bredere governance- en risicomanagementproces van de organisatie. Een praktisch vertrekpunt is het inrichten van een periodieke reviewcyclus, bijvoorbeeld per kwartaal, waarin de effectiviteit van monitoring wordt beoordeeld. Tijdens deze sessies bekijkt u samen met het SOC, operations en compliance-teams onder andere: welke logs worden daadwerkelijk gebruikt voor incidentdetectie, welke diagnostische instellingen zijn overbodig geworden door architectuurwijzigingen, of retentie-instellingen nog steeds voldoen aan compliance-vereisten, en welke kostenbesparingen mogelijk zijn zonder verlies van zichtbaarheid. Het PowerShell-script kan hier direct input voor leveren door te rapporteren welke workspaces weinig data genereren, welke resources diagnostische instellingen missen, en of retentie-instellingen consistent zijn geconfigureerd. Op basis van deze informatie kunt u gericht bijsturen: onnodige configuraties uitfaseren, ontbrekende instrumentatie toevoegen en retentie-instellingen afstemmen op actuele compliance-vereisten. Governance betekent ook dat eigenaarschap over monitoring-configuraties expliciet wordt toegewezen. Voor elke Log Analytics workspace en kritieke workload moet duidelijk zijn wie verantwoordelijk is voor het beheer van de bijbehorende configuraties, hoe wijzigingen worden aangevraagd en goedgekeurd, en hoe kennis wordt geborgd bij personeelswisselingen. In de context van Nederlandse overheidsorganisaties is het verstandig om dit eigenaarschap te koppelen aan bestaande rollen binnen de informatiebeveiligings- en continuïteitsorganisatie, zoals lijnmanagers, applicatie-eigenaren en de CISO. Leg vast dat grote wijzigingen in monitoring-configuraties altijd via het changeproces lopen en dat bij ingrijpende wijzigingen – bijvoorbeeld het wijzigen van retentie-instellingen voor auditlogs – expliciet akkoord van compliance of security nodig is. Door azure-monitor-configuration.ps1 periodiek als onafhankelijke controle te draaien, krijgt de CISO inzicht in de daadwerkelijke status van de monitoring-inrichting en kan hij of zij gericht vragen stellen aan teams waar afwijkingen worden geconstateerd.

Compliance, Audit en Bewijsvoering rondom Azure Monitor Configuratie

Azure Monitor-configuraties spelen een belangrijke rol in het aantonen van compliance met uiteenlopende kaders zoals de BIO, ISO 27001 en NIS2. Toezichthouders en auditors vragen steeds vaker niet alleen óf logging is ingericht, maar ook hoe de organisatie waarborgt dat relevante gebeurtenissen tijdig worden gesignaleerd, opgeslagen en geanalyseerd. Tijdens audits worden bijvoorbeeld vragen gesteld als: hoe weet u dat alle kritieke resources correct zijn geïnstrumenteerd? Hoe borgt u dat auditlogs lang genoeg worden bewaard voor compliance-vereisten? En hoe voorkomt u dat wijzigingen in architectuur leiden tot verlies van monitoring-capaciteiten? Een goed gedocumenteerde Azure Monitor-architectuur, gecombineerd met aantoonbare reviewcycli en scriptgestuurde controles, vormt het antwoord op deze vragen. Voor de BIO sluiten Azure Monitor-configuraties vooral aan bij de normen rond logging, monitoring en incidentrespons. Door in het informatiebeveiligingsbeleid expliciet op te nemen dat kritieke processen ondersteund worden door Azure Monitor met gedefinieerde retentie-instellingen en diagnostische instellingen, en door de concrete invulling te documenteren per workload, kan de organisatie richting ENSIA-auditors onderbouwen dat monitoring structureel is ingericht. Het PowerShell-script levert daarbij concreet auditbewijs in de vorm van exports die tonen welke workspaces actief zijn, welke retentie-instellingen zijn geconfigureerd, welke resources diagnostische instellingen hebben en hoe deze zijn gekoppeld aan incidentresponse-processen. Deze exports kunnen worden bewaard in een auditdossier, samen met besluiten uit de periodieke reviewmeetings en runbooks die beschrijven hoe het SOC of beheerteam gebruik maakt van monitoring-data voor incidentdetectie. Voor ISO 27001 en NIS2 is vooral van belang dat er een aantoonbare PDCA-cyclus (Plan-Do-Check-Act) bestaat rondom monitoring en observability. Het plan-niveau wordt ingevuld via architectuur- en beleidsdocumenten, de do-fase via implementatie van Log Analytics workspaces en diagnostische instellingen, de check-fase via periodieke analyses en scriptgestuurde controles, en de act-fase via verbetermaatregelen op basis van bevindingen en incidenten. Door deze samenhang expliciet te maken in documentatie en tijdens audits te illustreren met concrete voorbeelden – bijvoorbeeld een incident waarbij monitoring een dreiging vroegtijdig signaleerde, of een oefening waarin het gebruik van Log Analytics voor forensisch onderzoek is getest – ontstaat een overtuigend beeld van volwassen monitoring. Het gebruik van azure-monitor-configuration.ps1 als standaardinstrument in deze check-fase toont bovendien aan dat de organisatie niet afhankelijk is van handmatige controles, maar geautomatiseerde waarborgen inzet om de kwaliteit van monitoring-configuraties op niveau te houden.

Gebruik PowerShell-script azure-monitor-configuration.ps1 (functie Invoke-Revert) – Biedt waar nodig een gecontroleerd mechanisme om test- of tijdelijke monitoring-configuraties terug te draaien naar een eerder vastgelegde, goedgekeurde staat..

Compliance & Frameworks

Automation

Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).

PowerShell
<# .SYNOPSIS Inventariseert en beoordeelt Azure Monitor-configuraties voor kritieke workloads. .DESCRIPTION Dit script leest per abonnement de geconfigureerde Azure Monitor-componenten uit en beoordeelt of deze voldoen aan minimale eisen voor logging, monitoring en compliance. De nadruk ligt op: - Aanwezigheid en configuratie van Log Analytics workspaces met juiste retentie-instellingen - Aanwezigheid van diagnostische instellingen op kritieke resources - Configuratie van Log Analytics agents voor hybride omgevingen - Tagging en governance van monitoring-resources Met de parameter -Monitoring wordt een samenvattend compliance-overzicht getoond. Met -Remediation worden voorstellen gedaan voor standaard-configuraties en kan, indien gewenst, een basisset monitoring-configuraties worden aangemaakt voor met tags gemarkeerde kritieke resources. .NOTES Filename: azure-monitor-configuration.ps1 Author: Nederlandse Baseline voor Veilige Cloud Version: 1.0 Related JSON: content/azure/monitoring/azure-monitor-configuration.json Category: monitoring Workload: azure .LINK https://github.com/m365-tenant-best-practise .EXAMPLE .\azure-monitor-configuration.ps1 -Monitoring Controleert de huidige Azure Monitor-configuraties en rapporteert de compliance-status. .EXAMPLE .\azure-monitor-configuration.ps1 -Remediation -WhatIf Toont welke standaard-configuraties zouden worden aangemaakt voor kritieke resources. .EXAMPLE .\azure-monitor-configuration.ps1 -Remediation Maakt standaard-configuraties aan voor met tags gemarkeerde kritieke resources. #> #Requires -Version 5.1 #Requires -Modules Az.Accounts, Az.Monitor, Az.OperationalInsights, Az.Resources [CmdletBinding()] param( [Parameter(HelpMessage = "Monitor current configuration status")] [switch]$Monitoring, [Parameter(HelpMessage = "Apply recommended configuration")] [switch]$Remediation, [Parameter(HelpMessage = "Revert to previous configuration")] [switch]$Revert, [Parameter(HelpMessage = "Show what would happen without making changes")] [switch]$WhatIf ) $ErrorActionPreference = 'Stop' # ============================================================================ # HELPER: CONNECTIEBEHEER # ============================================================================ function Get-AzContextOrWarning { <# .SYNOPSIS Zorgt voor een geldige Azure-context zonder interactieve prompts. .DESCRIPTION In omgevingen zonder vooraf ingestelde context geeft deze functie een duidelijke waarschuwing en retourneert $null. Dit voorkomt dat scripts blijven hangen op interactieve logins in geautomatiseerde pipelines. #> [CmdletBinding()] param() $ctx = Get-AzContext -ErrorAction SilentlyContinue if (-not $ctx) { Write-Warning "Geen actieve Azure-context gevonden. Meld u vooraf aan met 'Connect-AzAccount' (bij voorkeur non-interactief, bijvoorbeeld via managed identity of service principal)." return $null } return $ctx } # ============================================================================ # FUNCTIONS # ============================================================================ function Test-Compliance { <# .SYNOPSIS Tests if current configuration meets compliance requirements .DESCRIPTION Wrapper function that calls Invoke-Monitoring and returns compliance status .OUTPUTS Returns monitoring result object with isCompliant property #> [CmdletBinding()] param() return Invoke-Monitoring } function Invoke-Monitoring { <# .SYNOPSIS Monitors and reports current Azure Monitor configuration status .DESCRIPTION Controleert per abonnement en resource: - Of Log Analytics workspaces correct zijn geconfigureerd met retentie-instellingen - Of kritieke resources diagnostische instellingen hebben - Of workspaces correct zijn getagd en voldoen aan governance-vereisten .OUTPUTS Hashtable met: - isCompliant: Boolean - timestamp: Datum/tijd - findings: Lijst met tekstuele bevindingen - summary: Overzicht met aantallen workspaces en kritieke afwijkingen #> [CmdletBinding()] param() try { Write-Host "`nMonitoring Azure Monitor-configuraties..." -ForegroundColor Yellow $ctx = Get-AzContextOrWarning if (-not $ctx) { return @{ isCompliant = $false timestamp = Get-Date findings = @("Geen Azure-context beschikbaar; voer Connect-AzAccount uit voordat u deze controle draait.") summary = @{ SubscriptionsChecked = 0 WorkspacesChecked = 0 WorkspacesWithoutRetention = 0 CriticalResourcesWithoutDiag = 0 WorkspacesWithoutTags = 0 } } } Write-Host "Context: $($ctx.Subscription.Name) ($($ctx.Subscription.Id))" -ForegroundColor Gray $result = @{ isCompliant = $true timestamp = Get-Date findings = @() summary = @{ SubscriptionsChecked = 0 WorkspacesChecked = 0 WorkspacesWithoutRetention = 0 CriticalResourcesWithoutDiag = 0 WorkspacesWithoutTags = 0 } } $subscriptions = Get-AzSubscription -ErrorAction Stop foreach ($sub in $subscriptions) { Set-AzContext -SubscriptionId $sub.Id -ErrorAction Stop | Out-Null $result.summary.SubscriptionsChecked++ Write-Host "`nAbonnement: $($sub.Name) [$($sub.Id)]" -ForegroundColor Cyan # Controleer Log Analytics workspaces $workspaces = Get-AzOperationalInsightsWorkspace -ErrorAction SilentlyContinue foreach ($ws in $workspaces) { $result.summary.WorkspacesChecked++ Write-Host " Controleren workspace: $($ws.Name)" -ForegroundColor White # Controleer retentie-instellingen (minimum 90 dagen voor compliance) $retentionDays = $ws.RetentionInDays if (-not $retentionDays -or $retentionDays -lt 90) { $result.isCompliant = $false $result.summary.WorkspacesWithoutRetention++ $msg = "Workspace '$($ws.Name)' in abonnement '$($sub.Name)' heeft geen of onvoldoende retentie-instelling (huidig: $retentionDays dagen, minimum: 90 dagen)." $result.findings += $msg Write-Host " [FAIL] $msg" -ForegroundColor Red } else { Write-Host " [OK] Workspace '$($ws.Name)' heeft retentie van $retentionDays dagen." -ForegroundColor Green } # Controleer tags (minimum vereiste tags voor governance) $requiredTags = @("Environment", "Owner", "InformationClassification") $missingTags = @() foreach ($tag in $requiredTags) { if (-not $ws.Tags -or -not $ws.Tags.ContainsKey($tag)) { $missingTags += $tag } } if ($missingTags.Count -gt 0) { $result.isCompliant = $false $result.summary.WorkspacesWithoutTags++ $msg = "Workspace '$($ws.Name)' in abonnement '$($sub.Name)' mist vereiste tags: $($missingTags -join ', ')." $result.findings += $msg Write-Host " [WARN] $msg" -ForegroundColor Yellow } else { Write-Host " [OK] Workspace '$($ws.Name)' heeft alle vereiste tags." -ForegroundColor Green } } # Controleer diagnostische instellingen op kritieke resources $resourceGroups = Get-AzResourceGroup -ErrorAction Stop $criticalGroups = $resourceGroups | Where-Object { $_.Tags.Keys -contains "Critical" -and $_.Tags["Critical"] -eq "True" } foreach ($rg in $criticalGroups) { Write-Host " Controleren resourcegroep (kritiek): $($rg.ResourceGroupName)" -ForegroundColor White $resources = Get-AzResource -ResourceGroupName $rg.ResourceGroupName -ErrorAction SilentlyContinue foreach ($resource in $resources) { # Controleer of resource diagnostische instellingen heeft $diagSettings = Get-AzDiagnosticSetting -ResourceId $resource.ResourceId -ErrorAction SilentlyContinue if (-not $diagSettings -or $diagSettings.Count -eq 0) { $result.isCompliant = $false $result.summary.CriticalResourcesWithoutDiag++ $msg = "Kritieke resource '$($resource.Name)' (type: $($resource.ResourceType)) in resourcegroep '$($rg.ResourceGroupName)' heeft geen diagnostische instellingen geconfigureerd." $result.findings += $msg Write-Host " [FAIL] $msg" -ForegroundColor Red } else { Write-Host " [OK] Resource '$($resource.Name)' heeft diagnostische instellingen geconfigureerd." -ForegroundColor Green } } } } Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "SAMENVATTING AZURE MONITOR CONFIGURATIE" -ForegroundColor Cyan Write-Host (" Abonnementen gecontroleerd : {0}" -f $result.summary.SubscriptionsChecked) -ForegroundColor White Write-Host (" Workspaces gecontroleerd : {0}" -f $result.summary.WorkspacesChecked) -ForegroundColor White $colorRetention = 'Green' if ($result.summary.WorkspacesWithoutRetention -gt 0) { $colorRetention = 'Yellow' } Write-Host (" Workspaces zonder retentie : {0}" -f $result.summary.WorkspacesWithoutRetention) -ForegroundColor $colorRetention $colorTags = 'Green' if ($result.summary.WorkspacesWithoutTags -gt 0) { $colorTags = 'Yellow' } Write-Host (" Workspaces zonder vereiste tags : {0}" -f $result.summary.WorkspacesWithoutTags) -ForegroundColor $colorTags $colorDiag = 'Green' if ($result.summary.CriticalResourcesWithoutDiag -gt 0) { $colorDiag = 'Red' } Write-Host (" Kritieke resources zonder diagnostiek : {0}" -f $result.summary.CriticalResourcesWithoutDiag) -ForegroundColor $colorDiag if ($result.isCompliant) { Write-Host "`n[OK] COMPLIANT: Azure Monitor-configuraties voldoen aan minimale vereisten." -ForegroundColor Green } else { Write-Host "`n[FAIL] NON-COMPLIANT: Zie bevindingen voor ontbrekende configuraties." -ForegroundColor Red } return $result } catch { Write-Host "`n[FAIL] ERROR tijdens monitoring: $_" -ForegroundColor Red throw } } function Invoke-Remediation { <# .SYNOPSIS Biedt ondersteuning bij het aanmaken van standaard Azure Monitor-configuraties. .DESCRIPTION Zoekt kritieke resources zonder diagnostische instellingen en kan, indien bevestigd, standaard diagnostische instellingen aanmaken die logs naar een Log Analytics workspace sturen. Gebruik bij voorkeur -WhatIf om de impact te beoordelen. .PARAMETER WhatIf Shows what would be changed without making actual changes #> [CmdletBinding(SupportsShouldProcess)] param() try { Write-Host "`nRemediation van Azure Monitor-configuraties..." -ForegroundColor Yellow $ctx = Get-AzContextOrWarning if (-not $ctx) { Write-Warning "Remediation kan niet worden uitgevoerd zonder geldige Azure-context." return } $subscriptions = Get-AzSubscription -ErrorAction Stop foreach ($sub in $subscriptions) { Set-AzContext -SubscriptionId $sub.Id -ErrorAction Stop | Out-Null Write-Host "`nAbonnement: $($sub.Name) [$($sub.Id)]" -ForegroundColor Cyan # Zoek een geschikte Log Analytics workspace (bij voorkeur in dezelfde resourcegroep of een centrale workspace) $workspaces = Get-AzOperationalInsightsWorkspace -ErrorAction SilentlyContinue $targetWorkspace = $workspaces | Select-Object -First 1 if (-not $targetWorkspace) { Write-Warning "Geen Log Analytics workspace gevonden in abonnement '$($sub.Name)'. Maak eerst een workspace aan voordat u diagnostische instellingen configureert." continue } Write-Host " Doel-workspace: $($targetWorkspace.Name)" -ForegroundColor Gray $resourceGroups = Get-AzResourceGroup -ErrorAction Stop $criticalGroups = $resourceGroups | Where-Object { $_.Tags.Keys -contains "Critical" -and $_.Tags["Critical"] -eq "True" } foreach ($rg in $criticalGroups) { $resources = Get-AzResource -ResourceGroupName $rg.ResourceGroupName -ErrorAction SilentlyContinue foreach ($resource in $resources) { # Controleer of resource al diagnostische instellingen heeft $existingDiag = Get-AzDiagnosticSetting -ResourceId $resource.ResourceId -ErrorAction SilentlyContinue if ($existingDiag -and $existingDiag.Count -gt 0) { Write-Host " [INFO] Resource '$($resource.Name)' heeft al diagnostische instellingen; geen standaard-configuratie aangemaakt." -ForegroundColor Gray continue } # Bepaal welke logs beschikbaar zijn voor dit resource type $availableCategories = @() try { $metricCategories = Get-AzMetricDefinition -ResourceId $resource.ResourceId -ErrorAction SilentlyContinue $logCategories = Get-AzDiagnosticSettingCategory -ResourceId $resource.ResourceId -ErrorAction SilentlyContinue if ($logCategories) { $availableCategories = $logCategories | Where-Object { $_.CategoryType -eq "Logs" } | Select-Object -ExpandProperty Name } } catch { Write-Verbose "Kon geen diagnostische categorieën ophalen voor resource '$($resource.Name)': $_" } if ($availableCategories.Count -eq 0) { Write-Host " [SKIP] Resource '$($resource.Name)' (type: $($resource.ResourceType)) ondersteunt geen diagnostische instellingen." -ForegroundColor Yellow continue } $diagName = "default-diagnostic-setting" Write-Host " [PLAN] Standaard diagnostische instelling aanmaken voor '$($resource.Name)'..." -ForegroundColor Yellow if ($PSCmdlet.ShouldProcess($resource.ResourceId, "Create diagnostic setting '$diagName'")) { try { $params = @{ ResourceId = $resource.ResourceId Name = $diagName WorkspaceId = $targetWorkspace.ResourceId Enabled = $true Category = $availableCategories RetentionEnabled = $true RetentionInDays = 365 } Set-AzDiagnosticSetting @params -ErrorAction Stop | Out-Null Write-Host " [OK] Standaard diagnostische instelling '$diagName' aangemaakt voor resource '$($resource.Name)'." -ForegroundColor Green } catch { Write-Warning "Kon diagnostische instelling niet aanmaken voor '$($resource.Name)': $_" } } } } } Write-Host "`n[OK] Remediation uitgevoerd (of gesimuleerd met WhatIf)." -ForegroundColor Green } catch { Write-Host "`n[FAIL] ERROR tijdens remediation: $_" -ForegroundColor Red throw } } function Invoke-Revert { <# .SYNOPSIS Reverts configuration to previous state .DESCRIPTION In deze baseline is geen volledige state-tracking voor Azure Monitor-configuraties geïmplementeerd. Deze functie verwijdert uitsluitend standaard diagnostische instellingen met de naam 'default-diagnostic-setting' die door dit script zijn aangemaakt. #> [CmdletBinding(SupportsShouldProcess)] param() try { Write-Host "`nRevert van standaard Azure Monitor-configuraties..." -ForegroundColor Yellow $ctx = Get-AzContextOrWarning if (-not $ctx) { Write-Warning "Revert kan niet worden uitgevoerd zonder geldige Azure-context." return } $subscriptions = Get-AzSubscription -ErrorAction Stop foreach ($sub in $subscriptions) { Set-AzContext -SubscriptionId $sub.Id -ErrorAction Stop | Out-Null Write-Host "`nAbonnement: $($sub.Name) [$($sub.Id)]" -ForegroundColor Cyan $resourceGroups = Get-AzResourceGroup -ErrorAction Stop $criticalGroups = $resourceGroups | Where-Object { $_.Tags.Keys -contains "Critical" -and $_.Tags["Critical"] -eq "True" } foreach ($rg in $criticalGroups) { $resources = Get-AzResource -ResourceGroupName $rg.ResourceGroupName -ErrorAction SilentlyContinue foreach ($resource in $resources) { $diagSettings = Get-AzDiagnosticSetting -ResourceId $resource.ResourceId -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq "default-diagnostic-setting" } foreach ($diag in $diagSettings) { Write-Host " [PLAN] Verwijderen standaard diagnostische instelling '$($diag.Name)' van resource '$($resource.Name)'..." -ForegroundColor Yellow if ($PSCmdlet.ShouldProcess($resource.ResourceId, "Remove diagnostic setting '$($diag.Name)'")) { try { Remove-AzDiagnosticSetting -ResourceId $resource.ResourceId -Name $diag.Name -ErrorAction Stop Write-Host " [OK] Diagnostische instelling '$($diag.Name)' verwijderd." -ForegroundColor Green } catch { Write-Warning "Kon diagnostische instelling niet verwijderen: $_" } } } } } } Write-Host "`n[OK] Revert van standaard-configuraties voltooid (of gesimuleerd met WhatIf)." -ForegroundColor Green } catch { Write-Host "`n[FAIL] ERROR tijdens revert: $_" -ForegroundColor Red throw } } # ============================================================================ # HEADER # ============================================================================ Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Azure Monitor Configuration" -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan # ============================================================================ # MAIN EXECUTION # ============================================================================ try { if ($Revert) { if ($WhatIf) { Write-Host "WhatIf: Zou standaard diagnostische instellingen verwijderen (default-diagnostic-setting)." -ForegroundColor Yellow } else { Invoke-Revert } } elseif ($Remediation) { if ($WhatIf) { Write-Host "WhatIf: Zou standaard diagnostische instellingen aanmaken voor kritieke resources." -ForegroundColor Yellow } else { Invoke-Remediation } } elseif ($Monitoring) { $result = Invoke-Monitoring if ($result.isCompliant) { exit 0 } else { exit 1 } } else { Write-Host "Beschikbare parameters:" -ForegroundColor Yellow Write-Host " -Monitoring : Controleer huidige status van Azure Monitor-configuraties" -ForegroundColor Gray Write-Host " -Remediation : Stel standaard-configuraties voor en maak deze desgewenst aan" -ForegroundColor Gray Write-Host " -Revert : Verwijder standaard-configuraties (default-diagnostic-setting)" -ForegroundColor Gray Write-Host " -WhatIf : Toon welke wijzigingen zouden worden uitgevoerd" -ForegroundColor Gray Write-Host "`nVoorbeeld: .\azure-monitor-configuration.ps1 -Monitoring" -ForegroundColor Cyan } } catch { Write-Error "Script execution failed: $_" exit 2 } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } # ============================================================================ # EXIT CODES # ============================================================================ # 0 = Success / Compliant # 1 = Warning / Non-compliant # 2 = Error / Execution failed

Risico zonder implementatie

Risico zonder implementatie
High: Zonder goed ontworpen en centraal beheerde Azure Monitor-configuraties blijven kritieke beveiligings- en beschikbaarheidsincidenten onzichtbaar, worden compliance-vereisten niet nageleefd, lopen kosten onbeheersbaar op en kan de organisatie richting toezichthouders niet aantonen dat monitoring op orde is. Dit vergroot de kans op langdurige uitval, gegevensverlies, reputatieschade en non-compliance met BIO, ISO 27001 en NIS2.

Management Samenvatting

Richt een gestructureerde Azure Monitor-architectuur in met Log Analytics workspaces, diagnostische instellingen en retentie-instellingen die afgestemd zijn op compliance-vereisten. Automatiseer de uitrol en inventarisatie van monitoring-configuraties met PowerShell en Infrastructure as Code, gebruik azure-monitor-configuration.ps1 om de inrichting periodiek te toetsen en verbeter deze op basis van incidenten en audits. Zo borgt u dat relevante gebeurtenissen tijdig worden gedetecteerd, opgeslagen en geanalyseerd, en dat monitoring aantoonbaar wordt gemaakt richting bestuur en toezichthouders.