Azure Arc: Hybride En Multi-cloud Beheer En Governance

💼 Management Samenvatting

Azure Arc biedt Nederlandse overheidsorganisaties de mogelijkheid om servers, Kubernetes-clusters en databases die buiten Azure draaien – in eigen datacenters, bij andere cloudproviders of in gespecialiseerde hostingomgevingen – te beheren alsof ze native Azure-resources zijn. Door resources te registreren via Azure Arc ontstaat een uniforme besturingslaag waarmee governance, beveiliging, compliance en operationeel beheer centraal kunnen worden georganiseerd, ongeacht waar resources fysiek zijn ondergebracht.

Aanbeveling
IMPLEMENTEER AZURE ARC VOOR CENTRALE GOVERNANCE VAN HYBRIDE EN MULTI-CLOUD RESOURCES
Risico zonder
High
Risk Score
8/10
Implementatie
200u (tech: 120u)
Van toepassing op:
Azure
Azure Arc
Hybride omgevingen
Multi-cloud
On-premises servers
Kubernetes
SQL Server
PostgreSQL

Nederlandse publieke organisaties werken steeds vaker in hybride omgevingen waarbij workloads zijn verdeeld over meerdere locaties: eigen datacenters voor gevoelige systemen, Azure voor moderne cloudtoepassingen, andere cloudproviders voor specifieke services en gespecialiseerde hosting voor ketenvoorzieningen. Zonder een centraal beheerplatform leidt dit tot gefragmenteerde landschappen waarin iedere omgeving zijn eigen configuratie, toegangsmodel, beveiligingsmaatregelen en complianceprocessen hanteert. Dit creëert aanzienlijke risico's op inconsistente beveiligingsconfiguraties, onvoldoende zichtbaarheid in bedreigingen en misconfiguraties, beperkte auditbaarheid en moeilijke compliance-rapportage over meerdere omgevingen heen. Bovendien vragen BIO, NIS2 en sectorale kaders om aantoonbare controle en governance over alle bedrijfskritische IT-diensten, ook wanneer deze buiten de eigen Azure-tenant draaien. Azure Arc lost deze uitdagingen op door een uniforme interface te bieden waarmee servers, containers en databases kunnen worden ingeschreven in dezelfde governance-, beveiligings- en complianceprocessen als native Azure-resources. Door beleid, monitoring, configuratiebeheer, toegangscontrole en rapportages centraal te organiseren, wordt het mogelijk om hybride en multi-cloud landschappen op een beheerste, veilige en transparante manier te exploiteren zonder in te leveren op flexibiliteit of lokale autonomie.

PowerShell Modules Vereist
Primary API: Azure Resource Manager (ARM), Azure Arc Resource Bridge
Connection: Connect-AzAccount
Required Modules: Az.Accounts, Az.Resources, Az.ResourceGraph, Az.ConnectedMachine

Implementatie

Dit artikel biedt een overzicht van Azure Arc en de mogelijkheden voor hybride en multi-cloud beheer binnen de Nederlandse publieke sector. We behandelen de architectuur en componenten van Azure Arc, de verschillende Arc-enabled services (servers, Kubernetes, data services), de governance- en beveiligingsmogelijkheden, en de integratie met bestaande Azure-diensten zoals Azure Policy, Azure Monitor en Microsoft Defender voor Cloud. Daarnaast gaan we in op use cases voor Nederlandse overheidsorganisaties, implementatiestrategieën en best practices voor een veilige en gecontroleerde uitrol. Het bijbehorende PowerShell-script ondersteunt bij het inventariseren van alle Arc-verbonden resources, het bepalen van de governance- en compliance-status en het genereren van overzichten die aansluiten op de Nederlandse Baseline voor Veilige Cloud.

Azure Arc-architectuur en basisconcepten

Azure Arc fungeert als een uitbreidingslaag bovenop Azure Resource Manager (ARM) die resources buiten Azure in staat stelt om deel te nemen aan Azure's governance, beveiliging en operationele processen. De kerncomponenten van Azure Arc zijn de Arc-agents die op de doelresources worden geïnstalleerd en een veilige, geverifieerde verbinding onderhouden met Azure via uitgaande HTTPS-verbindingen. Deze agents verzamelen metadata, configuratie-informatie en telemetrie, en maken het mogelijk dat Azure services zoals Azure Policy, Azure Monitor en Microsoft Defender voor Cloud deze resources kunnen behandelen alsof ze native in Azure draaien. Voor Nederlandse overheidsorganisaties betekent dit dat bestaande on-premises infrastructuur, servers in andere clouds of gespecialiseerde omgevingen kunnen profiteren van dezelfde beveiligings-, compliance- en beheerstandaarden als Azure-resources, zonder dat deze resources daadwerkelijk naar Azure hoeven te worden gemigreerd.

De architectuur van Azure Arc is gebaseerd op een resource bridge-concept waarbij Arc-enabled resources worden geregistreerd als Azure-resources met een specifiek resource type, zoals 'Microsoft.HybridCompute/machines' voor servers, 'Microsoft.Kubernetes/connectedClusters' voor Kubernetes-clusters, of 'Microsoft.AzureArcData/sqlServerInstances' voor SQL Server. Deze resources verschijnen in de Azure Portal naast native Azure-resources, kunnen worden getagd en gegroepeerd volgens dezelfde naamgevings- en organisatieconventies, en kunnen deel uitmaken van dezelfde management group-hiërarchieën en abonnementstructuren. Belangrijk is dat de resources zelf fysiek blijven staan waar ze zijn: Arc creëert geen data-replicatie, geen migratie van workloads en geen wijziging aan de onderliggende infrastructuur. In plaats daarvan fungeert Arc als een besturings- en governance-laag die uniformiteit brengt in beheer, monitoring en compliance, ongeacht de fysieke locatie van de resources.

Azure Arc ondersteunt verschillende typen resources die relevant zijn voor Nederlandse overheidsorganisaties. Arc-enabled servers maken het mogelijk om Windows- en Linux-servers in datacenters, edge-locaties of andere clouds te beheren via Azure's server management- en securitydiensten, zoals Azure Update Management, Azure Automation, Microsoft Defender voor Servers en Azure Monitor. Arc-enabled Kubernetes breidt Azure's container governance uit naar clusters die buiten Azure draaien, inclusief on-premises Kubernetes, AKS on Azure Stack HCI, of clusters bij andere cloudproviders, waardoor uniform beleid, GitOps-configuraties en compliance-rapportage mogelijk worden. Arc-enabled SQL Server en PostgreSQL bieden centraal beheer en monitoring voor databases die buiten Azure draaien, inclusief patching, back-upconfiguratie en security assessments. Door deze verschillende Arc-services te combineren, kunnen organisaties een volledig hybride landschap centraal beheren vanuit één Azure-tenant, wat essentieel is voor het realiseren van de governance- en compliancevereisten uit de Nederlandse Baseline voor Veilige Cloud.

De beveiligingsarchitectuur van Azure Arc is gebouwd op het principe van least privilege en verifieerbare identiteit. Arc-agents gebruiken service principals of managed identities voor authenticatie met Azure, en alle communicatie verloopt via versleutelde HTTPS-verbindingen naar Azure-eindpunten. Agents hebben alleen de minimale rechten nodig om metadata te verzamelen en configuratiewijzigingen toe te passen die expliciet zijn geautoriseerd via Azure Policy of andere Azure-beheerinterfaces. Er is geen inkomende firewallregel nodig: alle verbindingen initiëren vanuit de Arc-agent naar Azure, wat de attack surface aanzienlijk verkleint. Voor Nederlandse overheidsorganisaties met strikte netwerksegmentatie en eisen aan dataresidency betekent dit dat Arc kan worden gebruikt zonder dat gevoelige data worden gerepliceerd naar Azure of dat inkomende poorten open moeten staan. De agents kunnen bovendien worden geconfigureerd om gebruik te maken van proxy's of specifieke netwerkpaden, zodat Arc kan worden geïntegreerd in bestaande security-architecturen zonder de perimeter te verzwakken.

Azure Arc-services en gebruiksmogelijkheden

Azure Arc-enabled servers vormen de basislaag voor hybride serverbeheer en bieden Nederlandse overheidsorganisaties de mogelijkheid om Windows- en Linux-servers die buiten Azure draaien te beheren alsof ze Azure Virtual Machines zijn. Eenmaal geregistreerd via Arc kunnen servers profiteren van Azure Update Management voor geautomatiseerd patchbeheer, Azure Automation voor runbook-uitvoering en configuratiebeheer, Azure Monitor voor uitgebreide monitoring en logging, en Microsoft Defender voor Servers voor geavanceerde bedreigingsbescherming. Dit is bijzonder waardevol voor organisaties met legacy-systemen die niet eenvoudig kunnen worden gemigreerd naar Azure, maar die wel moeten voldoen aan dezelfde beveiligings- en compliance-eisen als cloud-workloads. Door Arc-enabled servers te taggen met metadata zoals dataclassificatie, eigenaar, bedrijfsproces en omgeving, kunnen security- en beheerteams gericht beleid toepassen en rapportages genereren die aansluiten op informatiebeveiligingsregisters en risicomanagementprocessen.

Azure Arc-enabled Kubernetes brengt Azure's container governance naar clusters die buiten Azure draaien, wat cruciaal is voor Nederlandse overheidsorganisaties die containerplatformen gebruiken in meerdere omgevingen. Via Arc kunnen Kubernetes-clusters worden geregistreerd en vervolgens worden beheerd met Azure Policy voor Kubernetes, waarmee beveiligings- en configuratieregels centraal kunnen worden gedefinieerd en automatisch afgedwongen. GitOps via Flux v2 maakt het mogelijk om platformconfiguraties en applicatie-instellingen te beheren vanuit Git-repositories, wat naadloos aansluit op bestaande change- en releaseprocessen binnen de overheid. Arc-enabled Kubernetes integreert ook met Azure Monitor Container Insights voor gedetailleerde monitoring, en met Azure RBAC voor uniform toegangsbeheer over alle clusters heen. Voor organisaties met hybride Kubernetes-landschappen – bijvoorbeeld clusters in eigen datacenters voor gevoelige workloads en AKS in Azure voor publieksdiensten – maakt Arc het mogelijk om beide te behandelen als onderdeel van één governance-raamwerk, wat essentieel is voor het realiseren van consistente beveiliging en compliance over het hele containerplatform.

Azure Arc-enabled data services bieden beheer en governance voor SQL Server- en PostgreSQL-databases die buiten Azure draaien. Dit is relevant voor Nederlandse overheidsorganisaties die databases hebben in eigen datacenters of bij hostingpartners, maar die wel willen profiteren van Azure's database management- en securitydiensten. Arc-enabled SQL Server maakt het mogelijk om SQL Server-instances te registreren en vervolgens te monitoren via Azure Monitor, te beveiligen met Microsoft Defender voor SQL, en te patchen via Azure Update Management. Arc-enabled PostgreSQL biedt vergelijkbare mogelijkheden voor PostgreSQL-clusters, inclusief geautomatiseerde back-ups en security assessments. Voor organisaties met gevoelige databases die om dataresidency-redenen niet naar Azure kunnen worden gemigreerd, maar die wel moeten voldoen aan dezelfde beveiligings- en compliance-eisen als cloud-databases, biedt Arc een manier om deze databases op te nemen in centrale governance- en monitoringprocessen zonder de data zelf te verplaatsen.

Naast deze primaire Arc-services biedt Azure Arc ook extensies en integraties die de functionaliteit verder uitbreiden. VM-extensions kunnen worden geïnstalleerd op Arc-enabled servers om aanvullende Azure-services te activeren, zoals de Log Analytics-agent voor geavanceerde monitoring, de Azure Monitor-agent voor moderne telemetrie, of custom scripts voor specifieke configuratietaken. Azure Policy kan worden toegepast op Arc-resources om configuratiestandaarden af te dwingen en compliance te monitoren, net zoals voor native Azure-resources. Azure Resource Graph biedt krachtige query-mogelijkheden om Arc-resources te inventariseren, te filteren en te analyseren op basis van tags, locatie, type en andere eigenschappen. Voor Nederlandse overheidsorganisaties betekent dit dat Arc niet alleen een registratiesysteem is, maar een volwaardig platform voor hybride governance dat naadloos integreert met bestaande Azure-beveiligings- en complianceprocessen, waardoor hybride omgevingen kunnen worden behandeld als één geïntegreerd landschap dat voldoet aan de Nederlandse Baseline voor Veilige Cloud.

Governance, beveiliging en compliance met Azure Arc

Gebruik PowerShell-script index.ps1 (functie Invoke-Monitoring) – Inventariseert alle Arc-verbonden resources (servers, Kubernetes-clusters, data services) en controleert governance-, beveiligings- en compliance-aspecten zoals tagging, Azure Policy-toewijzingen en monitoring-configuraties..

Governance met Azure Arc begint bij volledige zichtbaarheid: organisaties kunnen alleen beleid afdwingen, risico's beoordelen en compliance rapporteren over resources die zijn geregistreerd in het Arc-platform. Het PowerShell-script in dit artikel ondersteunt deze visibiliteit door alle Arc-verbonden resources te inventariseren en de governance-status te beoordelen. Eenmaal geregistreerd kunnen Arc-resources worden getagd met metadata die essentieel is voor governance, zoals dataclassificatie (bijvoorbeeld Openbaar, Intern, Vertrouwelijk, Geheim), eigenaar, bedrijfsproces, omgeving en compliance-profielen (bijvoorbeeld BIO, NIS2, AVG). Deze tags vormen de basis voor geautomatiseerde policy-toewijzingen, waarbij resources met een hogere gevoeligheid automatisch strenger beleid krijgen dan minder kritieke omgevingen. Door tags consistent toe te passen en te valideren via Azure Policy, ontstaat een gestructureerd governance-raamwerk waarin resources kunnen worden gegroepeerd, gefilterd en beheerd op basis van hun risicoprofiel en bedrijfsbelang.

Azure Policy kan worden gebruikt om configuratie- en beveiligingsstandaarden af te dwingen op Arc-resources, net zoals voor native Azure-resources. Voor Arc-enabled servers kunnen policies worden gedefinieerd die eisen dat specifieke security-configuraties aanwezig zijn, dat monitoring-agents geïnstalleerd zijn, of dat bepaalde extensies zijn geconfigureerd. Voor Arc-enabled Kubernetes kunnen policies worden gebruikt om te eisen dat containers alleen images uit goedgekeurde registries gebruiken, dat pods niet in privileged modus draaien, of dat bepaalde labels verplicht zijn op namespaces en workloads. Door policies op management group-niveau of abonnementsniveau toe te wijzen aan Arc-resources, ontstaat een uniforme baseline die automatisch wordt gevalideerd wanneer nieuwe resources worden geregistreerd of wanneer configuraties wijzigen. Het PowerShell-script ondersteunt deze compliance-borging door de policy-status te controleren en overzichten te genereren van niet-conforme resources, inclusief aanbevelingen voor remediatie.

Beveiliging met Azure Arc wordt gerealiseerd door integratie met Microsoft Defender voor Cloud en andere Azure security-services. Arc-enabled servers kunnen worden beschermd met Microsoft Defender voor Servers, dat geavanceerde endpointdetectie- en responsmogelijkheden biedt, kwetsbaarheidsscans uitvoert en adaptieve applicatiecontroles afdwingt. Arc-enabled Kubernetes-clusters kunnen worden beveiligd met Microsoft Defender voor Containers, dat containerimages scant, runtime-threat detection biedt en network policies afdwingt. Arc-enabled SQL Server-instances kunnen worden beveiligd met Microsoft Defender voor SQL, dat kwetsbaarheidsscans uitvoert en anomaliedetectie biedt. Door deze security-services te activeren voor Arc-resources, kunnen organisaties hun hele hybride landschap beschermen met dezelfde geavanceerde threat detection- en responsmogelijkheden als voor native Azure-resources, wat essentieel is voor het realiseren van een uniforme security-posture over alle omgevingen heen.

Compliance-rapportage met Azure Arc wordt ondersteund door uitgebreide logging en monitoring via Azure Monitor en Log Analytics. Arc-agents verzamelen telemetrie over configuraties, prestatiemetrics, security-events en andere relevante gegevens, die worden opgeslagen in Log Analytics-werkruimten. Deze gegevens kunnen worden gebruikt om compliance-rapportages te genereren die aantonen welke resources aan welke policies voldoen, welke configuraties zijn toegepast, en welke afwijkingen zijn gedetecteerd. Azure Resource Graph biedt krachtige query-mogelijkheden om Arc-resources te inventariseren en te analyseren op basis van tags, policies, compliance-status en andere criteria. Het PowerShell-script in dit artikel benut deze informatiebronnen om gestructureerde overzichten te genereren die direct aansluiten op governance- en risicorapportages binnen de Nederlandse Baseline voor Veilige Cloud. Op basis hiervan kunnen CISO's, security officers en lijnmanagers onderbouwde beslissingen nemen over welke resources aanvullende maatregelen nodig hebben, welke uitzonderingen tijdelijk worden geaccepteerd, en welke verbeteracties in de roadmap moeten worden opgenomen. Door Arc-resources te integreren in bestaande SIEM-oplossingen en auditprocessen, wordt compliance-rapportage een automatisch en reproduceerbaar proces dat voldoet aan de eisen van toezichthouders en auditors.

Implementatiestrategie en best practices

Gebruik PowerShell-script index.ps1 (functie Invoke-Remediation) – Genereert een overzicht van Arc-resources met governance-hiaten en aanbevelingen voor verbetering, inclusief prioritering op basis van risico en bedrijfsimpact..

Een effectieve implementatie van Azure Arc begint bij een duidelijke strategie die rekening houdt met de specifieke context en vereisten van Nederlandse overheidsorganisaties. Het is belangrijk om te beginnen met een inventarisatie van bestaande resources die in aanmerking komen voor Arc-registratie: servers, Kubernetes-clusters en databases die buiten Azure draaien maar die wel moeten voldoen aan centrale governance- en beveiligingsstandaarden. Prioriteit moet worden gegeven aan bedrijfskritieke resources met gevoelige data, systemen die deel uitmaken van ketenvoorzieningen, en omgevingen die worden gebruikt voor publieksdiensten. Het PowerShell-script in dit artikel ondersteunt deze inventarisatie door een overzicht te genereren van bestaande Arc-resources en resources die nog niet zijn geregistreerd, zodat organisaties een gefaseerde implementatiestrategie kunnen ontwikkelen die aansluit bij risicoprofielen en bedrijfsbelang.

Bij het onboarden van resources via Azure Arc is het essentieel om direct de juiste governance- en security-parameters mee te geven. Dit begint bij de keuze van de resource group en het abonnement waarin Arc-resources worden geregistreerd, omdat hiermee de verantwoordelijke beheerafdeling, kostenplaats en security boundary worden bepaald. Kies een naamgevingsconventie waarin omgeving (ontwikkel, test, acceptatie, productie), organisatieonderdeel en locatie herkenbaar zijn, zodat resources later eenvoudig kunnen worden gefilterd en gegroepeerd. Koppel vervolgens tags aan elk Arc-resource volgens een gestandaardiseerd tag-schema, zoals dataclassificatie, eigenaar, contactpersoon, bedrijfsproces en compliance-profielen. Deze metadata vormt de basis voor geautomatiseerde policy-toewijzingen en rapportages, en moet consistent worden toegepast over alle Arc-resources heen. Het PowerShell-script controleert de aanwezigheid van vereiste tags en identificeert resources die aanvullende tagging nodig hebben voor volledige governance-dekking.

Beveiliging moet vanaf het begin worden meegenomen in de Arc-implementatie. Arc-agents moeten worden geïnstalleerd volgens best practices voor beveiliging, waarbij service principals of managed identities worden gebruikt voor authenticatie met minimale rechten. Netwerkverbindingen moeten worden geconfigureerd om gebruik te maken van proxy's of specifieke netwerkpaden wanneer dat nodig is, en firewallregels moeten worden gecontroleerd om te verzekeren dat alleen vereiste uitgaande verbindingen naar Azure-eindpunten zijn toegestaan. Arc-resources moeten direct worden gekoppeld aan Azure security-services zoals Microsoft Defender voor Cloud, zodat bedreigingsdetectie en -respons vanaf het moment van registratie actief zijn. Monitoring en logging moeten worden geconfigureerd om telemetrie te verzamelen in Log Analytics-werkruimten met de juiste retentie-instellingen en geografische locatie, rekening houdend met dataresidency-vereisten. Het PowerShell-script ondersteunt deze beveiligingsconfiguratie door te controleren of Arc-resources zijn gekoppeld aan security-services en monitoring-configuraties, en door aanbevelingen te genereren voor resources die aanvullende beveiligingsmaatregelen nodig hebben.

Een volwassen Arc-implementatie vereist ook processen voor operationeel beheer en continue verbetering. Organisaties moeten runbooks en playbooks ontwikkelen voor het onboarden van nieuwe resources, het monitoren van Arc-agent status, het reageren op connectivity-problemen en het afhandelen van compliance-afwijkingen. Deze processen moeten worden geïntegreerd in bestaande change management- en incidentresponsprocedures, zodat Arc-resources worden behandeld als onderdeel van het bredere IT-landschap. Regelmatige evaluaties moeten worden uitgevoerd om te beoordelen of Arc-resources nog steeds voldoen aan governance-standaarden, of policies effectief zijn, en waar verbeteringen mogelijk zijn. Het PowerShell-script ondersteunt deze operationele processen door gestructureerde overzichten te genereren van Arc-resources met governance-hiaten, inclusief aanbevelingen voor remediatie en prioritering op basis van risico en bedrijfsimpact. Door Arc te integreren in bestaande governance-, security- en complianceprocessen, wordt hybride beheer een duurzaam en schaalbaar onderdeel van de Nederlandse Baseline voor Veilige Cloud, dat organisaties in staat stelt om hybride en multi-cloud landschappen te beheren met dezelfde niveau van controle en transparantie als native Azure-omgevingen.

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 alle Azure Arc-verbonden resources en controleert governance- en compliance-aspecten. .DESCRIPTION Dit script inventariseert alle Arc-verbonden resources (servers, Kubernetes-clusters, data services) en beoordeelt in hoeverre governance-afspraken en beveiligingsmaatregelen zijn geïmplementeerd. Het controleert onder meer: - Aanwezigheid van Arc-enabled servers, Kubernetes-clusters en data services - Gebruik van consistente tagging voor eigenaarschap, classificatie en bedrijfsproces - Azure Policy-toewijzingen en compliance-status - Monitoring- en loggingconfiguraties In monitoringmodus wordt een rapport gegenereerd met de governance- en compliance-status per resource. In remediatiemodus wordt een overzicht gemaakt van resources met governance-hiaten, inclusief aanbevelingen voor vervolgstappen. .NOTES Filename: index.ps1 Author: Nederlandse Baseline voor Veilige Cloud Created: 2025-11-26 Last Modified: 2025-11-26 Version: 1.0 Related JSON: content/azure/arc/index.json .LINK https://github.com/[org]/m365-tenant-best-practise .EXAMPLE .\index.ps1 -Monitoring Voert een controle uit op alle Arc-verbonden resources en toont de governance-status. .EXAMPLE .\index.ps1 -Remediation Genereert een overzicht van resources met governance-hiaten en aanbevelingen voor verbetering. .EXAMPLE .\index.ps1 -Monitoring -LocalDebug Draait een lokale debug-run met gesimuleerde data zonder Azure-verbinding of Azure-API-calls. #> #Requires -Version 5.1 [CmdletBinding()] param( [Parameter()] [switch]$WhatIf, [Parameter()] [switch]$Monitoring, [Parameter()] [switch]$Remediation, [Parameter()] [string[]]$SubscriptionId, [Parameter()] [switch]$LocalDebug ) $ErrorActionPreference = 'Stop' $VerbosePreference = 'Continue' $PolicyName = "Azure Arc: hybride en multi-cloud beheer en governance" $PolicyDescription = "Controleert of Arc-verbonden resources (servers, Kubernetes-clusters, data services) zijn opgenomen in centrale governance, inclusief tagging, Azure Policy en monitoring-configuraties." function Test-ModuleAvailability { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string[]]$ModuleName ) foreach ($name in $ModuleName) { if (-not (Get-Module -ListAvailable -Name $name)) { Write-Warning "Vereiste module '$name' is niet geïnstalleerd. Installeer deze module voor volledige functionaliteit." } } } function Connect-RequiredServices { <# .SYNOPSIS Maakt verbinding met Azure als dat nog niet is gebeurd. #> [CmdletBinding()] param() if ($LocalDebug) { Write-Verbose "LocalDebug is ingeschakeld; er wordt geen Azure-verbinding opgezet." return } Test-ModuleAvailability -ModuleName @('Az.Accounts', 'Az.Resources', 'Az.ResourceGraph', 'Az.ConnectedMachine') try { $context = Get-AzContext -ErrorAction SilentlyContinue if (-not $context) { Write-Host "Verbinding maken met Azure..." -ForegroundColor Yellow Connect-AzAccount -ErrorAction Stop | Out-Null } else { Write-Verbose "Reeds verbonden met Azure: $($context.Subscription.Name)" } } catch { Write-Error "Kon geen verbinding maken met Azure: $_" throw } } function Get-DebugArcData { [CmdletBinding()] param() return @{ Servers = @( [PSCustomObject]@{ SubscriptionId = "00000000-0000-0000-0000-000000000010" SubscriptionName = "DBG-Overheid-NonProd" ResourceGroupName = "rg-arc-servers-nonprod" MachineName = "arc-srv-nonprod-01" Location = "westeurope" OsType = "Windows" HasRequiredTags = $true ClassificationTag = "Confidential" OwnerTag = "Team Infrastructuur" BusinessProcessTag = "Burgerportaal" HasDefenderEnabled = $true HasMonitoringAgent = $true HasGovernanceIssues = $false GovernanceIssues = @() }, [PSCustomObject]@{ SubscriptionId = "00000000-0000-0000-0000-000000000020" SubscriptionName = "DBG-Overheid-Prod" ResourceGroupName = "rg-arc-servers-prod" MachineName = "arc-srv-prod-01" Location = "northeurope" OsType = "Linux" HasRequiredTags = $false ClassificationTag = "" OwnerTag = "" BusinessProcessTag = "" HasDefenderEnabled = $false HasMonitoringAgent = $false HasGovernanceIssues = $true GovernanceIssues = @( "Ontbrekende kern-tags (Owner, BusinessProcess, DataClassification)", "Microsoft Defender voor Servers niet geactiveerd", "Geen monitoring-agent geïnstalleerd" ) } ) Kubernetes = @( [PSCustomObject]@{ SubscriptionId = "00000000-0000-0000-0000-000000000010" SubscriptionName = "DBG-Overheid-NonProd" ResourceGroupName = "rg-arc-k8s-nonprod" ClusterName = "arc-k8s-nonprod-01" Location = "westeurope" Distribution = "AKS on Azure Stack HCI" HasRequiredTags = $true ClassificationTag = "Confidential" OwnerTag = "Team Digitale Diensten" BusinessProcessTag = "Burgerportaal" HasKubernetesPolicies = $true NonCompliantPolicyCount = 0 HasGitOpsConfig = $true HasGovernanceIssues = $false GovernanceIssues = @() } ) DataServices = @() } } function Get-ArcServersStatus { <# .SYNOPSIS Haalt Arc-enabled servers op en bepaalt de governance-status. .OUTPUTS PSCustomObject met server- en governance-informatie. #> [CmdletBinding()] param() if ($LocalDebug) { Write-Verbose "Gebruik van gesimuleerde Arc-serverdata (LocalDebug)." return (Get-DebugArcData).Servers } Write-Verbose "Ophalen van Arc-enabled servers via Azure Resource Graph..." $query = @' resources | where type =~ "microsoft.hybridcompute/machines" | project id, name, location, subscriptionId, resourceGroup, tags, properties '@ $argParams = @{ Query = $query } if ($SubscriptionId) { $argParams['Subscription'] = $SubscriptionId } $machines = Search-AzGraph @argParams $results = @() foreach ($machine in $machines) { $props = $machine.properties $tags = $machine.tags $classification = $tags["DataClassification"] $owner = $tags["Owner"] $businessProc = $tags["BusinessProcess"] $hasRequiredTags = -not [string]::IsNullOrWhiteSpace($classification) -and ` -not [string]::IsNullOrWhiteSpace($owner) -and ` -not [string]::IsNullOrWhiteSpace($businessProc) $osType = if ($props.osType) { $props.osType } else { "Unknown" } $governanceIssues = @() $hasIssues = $false if (-not $hasRequiredTags) { $hasIssues = $true $governanceIssues += "Ontbrekende kern-tags (Owner, BusinessProcess of DataClassification)." } # Check voor Defender (vereenvoudigd - in productie via Defender API) $hasDefender = $false try { # Vereenvoudigde check: controleer of Defender extensies aanwezig zijn $extensions = $props.extensions if ($extensions) { $hasDefender = ($extensions | Where-Object { $_.type -like "*Defender*" }).Count -gt 0 } } catch { Write-Verbose "Kon Defender-status niet bepalen voor server $($machine.name): $_" } if (-not $hasDefender) { $hasIssues = $true $governanceIssues += "Microsoft Defender voor Servers niet geactiveerd of extensie niet geïnstalleerd." } # Check voor monitoring agent $hasMonitoring = $false try { $extensions = $props.extensions if ($extensions) { $hasMonitoring = ($extensions | Where-Object { $_.type -like "*LogAnalytics*" -or $_.type -like "*AzureMonitor*" }).Count -gt 0 } } catch { Write-Verbose "Kon monitoring-status niet bepalen voor server $($machine.name): $_" } if (-not $hasMonitoring) { $hasIssues = $true $governanceIssues += "Geen monitoring-agent (Log Analytics of Azure Monitor) geïnstalleerd." } $results += [PSCustomObject]@{ SubscriptionId = $machine.subscriptionId SubscriptionName = (Get-AzSubscription -SubscriptionId $machine.subscriptionId -ErrorAction SilentlyContinue).Name ResourceGroupName = $machine.resourceGroup MachineName = $machine.name Location = $machine.location OsType = $osType HasRequiredTags = $hasRequiredTags ClassificationTag = $classification OwnerTag = $owner BusinessProcessTag = $businessProc HasDefenderEnabled = $hasDefender HasMonitoringAgent = $hasMonitoring HasGovernanceIssues = $hasIssues GovernanceIssues = $governanceIssues } } return $results } function Get-ArcKubernetesStatus { <# .SYNOPSIS Haalt Arc-enabled Kubernetes-clusters op en bepaalt de governance-status. #> [CmdletBinding()] param() if ($LocalDebug) { Write-Verbose "Gebruik van gesimuleerde Arc-Kubernetes-data (LocalDebug)." return (Get-DebugArcData).Kubernetes } Write-Verbose "Ophalen van Arc-enabled Kubernetes-clusters via Azure Resource Graph..." $query = @' resources | where type =~ "microsoft.kubernetes/connectedclusters" | project id, name, location, subscriptionId, resourceGroup, tags, properties '@ $argParams = @{ Query = $query } if ($SubscriptionId) { $argParams['Subscription'] = $SubscriptionId } $clusters = Search-AzGraph @argParams $results = @() foreach ($cluster in $clusters) { $tags = $cluster.tags $classification = $tags["DataClassification"] $owner = $tags["Owner"] $businessProc = $tags["BusinessProcess"] $hasRequiredTags = -not [string]::IsNullOrWhiteSpace($classification) -and ` -not [string]::IsNullOrWhiteSpace($owner) -and ` -not [string]::IsNullOrWhiteSpace($businessProc) $distribution = if ($cluster.properties.distribution) { $cluster.properties.distribution } else { "Unknown" } $governanceIssues = @() $hasIssues = $false if (-not $hasRequiredTags) { $hasIssues = $true $governanceIssues += "Ontbrekende kern-tags (Owner, BusinessProcess of DataClassification)." } # Vereenvoudigde policy-check $nonCompliantCount = 0 $hasK8sPolicies = $false try { $policyResults = Get-AzPolicyState -Filter "resourceId eq '$($cluster.id)'" -ErrorAction SilentlyContinue if ($policyResults) { $hasK8sPolicies = $true $nonCompliantCount = ($policyResults | Where-Object { $_.ComplianceState -eq 'NonCompliant' }).Count if ($nonCompliantCount -gt 0) { $hasIssues = $true $governanceIssues += "Azure Policy rapporteert $nonCompliantCount niet-conforme beleidsregels." } } } catch { Write-Verbose "Kon policy-status niet bepalen voor cluster $($cluster.name): $_" } # GitOps-check (vereenvoudigd) $hasGitOps = $false try { $kustomizations = Get-AzResource -ResourceType "Microsoft.KubernetesConfiguration/fluxConfigurations" -ErrorAction SilentlyContinue | Where-Object { $_.Properties.clusterResourceId -eq $cluster.id } if ($kustomizations) { $hasGitOps = $true } else { $hasIssues = $true $governanceIssues += "Geen GitOps-configuratie (Flux) gevonden voor dit Arc-enabled Kubernetes-cluster." } } catch { Write-Verbose "Kon GitOps-configuraties niet ophalen voor cluster $($cluster.name): $_" } $results += [PSCustomObject]@{ SubscriptionId = $cluster.subscriptionId SubscriptionName = (Get-AzSubscription -SubscriptionId $cluster.subscriptionId -ErrorAction SilentlyContinue).Name ResourceGroupName = $cluster.resourceGroup ClusterName = $cluster.name Location = $cluster.location Distribution = $distribution HasRequiredTags = $hasRequiredTags ClassificationTag = $classification OwnerTag = $owner BusinessProcessTag = $businessProc HasKubernetesPolicies = $hasK8sPolicies NonCompliantPolicyCount = $nonCompliantCount HasGitOpsConfig = $hasGitOps HasGovernanceIssues = $hasIssues GovernanceIssues = $governanceIssues } } return $results } function Get-ArcDataServicesStatus { <# .SYNOPSIS Haalt Arc-enabled data services op en bepaalt de governance-status. #> [CmdletBinding()] param() if ($LocalDebug) { Write-Verbose "Gebruik van gesimuleerde Arc-data services-data (LocalDebug)." return (Get-DebugArcData).DataServices } Write-Verbose "Ophalen van Arc-enabled data services via Azure Resource Graph..." $query = @' resources | where type =~ "microsoft.azurearcdata/sqlServerInstances" or type =~ "microsoft.azurearcdata/postgresInstances" | project id, name, location, subscriptionId, resourceGroup, tags, type '@ $argParams = @{ Query = $query } if ($SubscriptionId) { $argParams['Subscription'] = $SubscriptionId } $dataServices = Search-AzGraph @argParams $results = @() foreach ($ds in $dataServices) { $tags = $ds.tags $classification = $tags["DataClassification"] $owner = $tags["Owner"] $businessProc = $tags["BusinessProcess"] $hasRequiredTags = -not [string]::IsNullOrWhiteSpace($classification) -and ` -not [string]::IsNullOrWhiteSpace($owner) -and ` -not [string]::IsNullOrWhiteSpace($businessProc) $serviceType = if ($ds.type -like "*sqlServer*") { "SQL Server" } else { "PostgreSQL" } $governanceIssues = @() $hasIssues = $false if (-not $hasRequiredTags) { $hasIssues = $true $governanceIssues += "Ontbrekende kern-tags (Owner, BusinessProcess of DataClassification)." } $results += [PSCustomObject]@{ SubscriptionId = $ds.subscriptionId SubscriptionName = (Get-AzSubscription -SubscriptionId $ds.subscriptionId -ErrorAction SilentlyContinue).Name ResourceGroupName = $ds.resourceGroup ServiceName = $ds.name Location = $ds.location ServiceType = $serviceType HasRequiredTags = $hasRequiredTags ClassificationTag = $classification OwnerTag = $owner BusinessProcessTag = $businessProc HasGovernanceIssues = $hasIssues GovernanceIssues = $governanceIssues } } return $results } function Test-Compliance { <# .SYNOPSIS Bepaalt de compliancestatus voor Azure Arc governance. .OUTPUTS PSCustomObject met samenvatting van de resultaten. #> [CmdletBinding()] param() $servers = Get-ArcServersStatus $kubernetes = Get-ArcKubernetesStatus $dataServices = Get-ArcDataServicesStatus $allResources = @( foreach ($s in $servers) { [PSCustomObject]@{ ResourceType = "Server" ResourceName = $s.MachineName SubscriptionId = $s.SubscriptionId SubscriptionName = $s.SubscriptionName HasGovernanceIssues = $s.HasGovernanceIssues GovernanceIssues = $s.GovernanceIssues } } foreach ($k in $kubernetes) { [PSCustomObject]@{ ResourceType = "Kubernetes" ResourceName = $k.ClusterName SubscriptionId = $k.SubscriptionId SubscriptionName = $k.SubscriptionName HasGovernanceIssues = $k.HasGovernanceIssues GovernanceIssues = $k.GovernanceIssues } } foreach ($d in $dataServices) { [PSCustomObject]@{ ResourceType = "DataService" ResourceName = $d.ServiceName SubscriptionId = $d.SubscriptionId SubscriptionName = $d.SubscriptionName HasGovernanceIssues = $d.HasGovernanceIssues GovernanceIssues = $d.GovernanceIssues } } ) if ($allResources.Count -eq 0) { Write-Verbose "Geen Arc-verbonden resources gevonden in de geselecteerde scope." return [PSCustomObject]@{ ScriptName = "azure-arc-overview" IsCompliant = $true Timestamp = Get-Date Details = "Er zijn geen Arc-verbonden resources gevonden in de huidige scope." Recommendations = @() Servers = @() Kubernetes = @() DataServices = @() } } $nonCompliant = $allResources | Where-Object { $_.HasGovernanceIssues } $isCompliant = ($nonCompliant.Count -eq 0) $details = if ($isCompliant) { "Alle gevonden Arc-verbonden resources voldoen aan de basis governance-vereisten." } else { "Een of meer Arc-verbonden resources hebben governance-hiaten die aandacht vereisen." } $recommendations = @() if (-not $isCompliant) { $recommendations += "Zorg dat alle Arc-resources kern-tags bevatten: Owner, BusinessProcess en DataClassification." $recommendations += "Activeer Microsoft Defender-services voor Arc-enabled servers en Kubernetes-clusters." $recommendations += "Installeer monitoring-agents (Log Analytics of Azure Monitor) op Arc-enabled servers." $recommendations += "Implementeer Azure Policy voor Arc-resources om configuratiestandaarden af te dwingen." $recommendations += "Configureer GitOps (Flux) voor Arc-enabled Kubernetes-clusters." $recommendations += "Documenteer governance-afspraken en neem Arc-resources op in incidentresponsprocedures." } return [PSCustomObject]@{ ScriptName = "azure-arc-overview" IsCompliant = $isCompliant Timestamp = Get-Date Details = $details Recommendations = $recommendations Servers = $servers Kubernetes = $kubernetes DataServices = $dataServices } } function Invoke-Monitoring { <# .SYNOPSIS Voert een monitoring-run uit en toont de governance-status per Arc-resource. #> [CmdletBinding()] param() Write-Host "`nMonitoring: $PolicyName" -ForegroundColor Yellow Write-Host "Beschrijving: $PolicyDescription" -ForegroundColor Yellow Write-Host "==============================================================" -ForegroundColor Yellow $result = Test-Compliance if ($result.Servers.Count -gt 0) { Write-Host "`nArc-enabled Servers:" -ForegroundColor Cyan foreach ($server in $result.Servers) { $statusColor = if (-not $server.HasGovernanceIssues) { "Green" } else { "Red" } $statusText = if (-not $server.HasGovernanceIssues) { "COMPLIANT" } else { "NON-COMPLIANT - $($server.GovernanceIssues.Count) issue(s)" } Write-Host ("- {0}/{1} ({2}, {3})" -f $server.SubscriptionName, $server.MachineName, $server.OsType, $server.Location) -ForegroundColor $statusColor Write-Host (" Tags: {0}" -f $(if ($server.HasRequiredTags) { "Aanwezig" } else { "Ontbrekend" })) -ForegroundColor Gray Write-Host (" Defender: {0}" -f $(if ($server.HasDefenderEnabled) { "Geactiveerd" } else { "Niet geactiveerd" })) -ForegroundColor Gray Write-Host (" Monitoring: {0}" -f $(if ($server.HasMonitoringAgent) { "Aanwezig" } else { "Afwezig" })) -ForegroundColor Gray Write-Host (" Status: {0}" -f $statusText) -ForegroundColor $statusColor if ($server.GovernanceIssues.Count -gt 0) { foreach ($issue in $server.GovernanceIssues) { Write-Host (" - {0}" -f $issue) -ForegroundColor Yellow } } Write-Host "" } } if ($result.Kubernetes.Count -gt 0) { Write-Host "Arc-enabled Kubernetes-clusters:" -ForegroundColor Cyan foreach ($cluster in $result.Kubernetes) { $statusColor = if (-not $cluster.HasGovernanceIssues) { "Green" } else { "Red" } $statusText = if (-not $cluster.HasGovernanceIssues) { "COMPLIANT" } else { "NON-COMPLIANT - $($cluster.GovernanceIssues.Count) issue(s)" } Write-Host ("- {0}/{1} ({2})" -f $cluster.SubscriptionName, $cluster.ClusterName, $cluster.Location) -ForegroundColor $statusColor Write-Host (" Distributie: {0}" -f $cluster.Distribution) -ForegroundColor Gray Write-Host (" Tags: {0}" -f $(if ($cluster.HasRequiredTags) { "Aanwezig" } else { "Ontbrekend" })) -ForegroundColor Gray Write-Host (" Azure Policy: {0} niet-conforme regels" -f $cluster.NonCompliantPolicyCount) -ForegroundColor Gray Write-Host (" GitOps: {0}" -f $(if ($cluster.HasGitOpsConfig) { "Aanwezig" } else { "Afwezig" })) -ForegroundColor Gray Write-Host (" Status: {0}" -f $statusText) -ForegroundColor $statusColor if ($cluster.GovernanceIssues.Count -gt 0) { foreach ($issue in $cluster.GovernanceIssues) { Write-Host (" - {0}" -f $issue) -ForegroundColor Yellow } } Write-Host "" } } if ($result.DataServices.Count -gt 0) { Write-Host "Arc-enabled Data Services:" -ForegroundColor Cyan foreach ($ds in $result.DataServices) { $statusColor = if (-not $ds.HasGovernanceIssues) { "Green" } else { "Red" } $statusText = if (-not $ds.HasGovernanceIssues) { "COMPLIANT" } else { "NON-COMPLIANT - $($ds.GovernanceIssues.Count) issue(s)" } Write-Host ("- {0}/{1} ({2}, {3})" -f $ds.SubscriptionName, $ds.ServiceName, $ds.ServiceType, $ds.Location) -ForegroundColor $statusColor Write-Host (" Tags: {0}" -f $(if ($ds.HasRequiredTags) { "Aanwezig" } else { "Ontbrekend" })) -ForegroundColor Gray Write-Host (" Status: {0}" -f $statusText) -ForegroundColor $statusColor if ($ds.GovernanceIssues.Count -gt 0) { foreach ($issue in $ds.GovernanceIssues) { Write-Host (" - {0}" -f $issue) -ForegroundColor Yellow } } Write-Host "" } } $totalCount = $result.Servers.Count + $result.Kubernetes.Count + $result.DataServices.Count if ($totalCount -eq 0) { Write-Host "`nGeen Arc-verbonden resources gevonden in de huidige scope." -ForegroundColor Cyan } if ($result.IsCompliant) { Write-Host "✅ COMPLIANT - Alle Arc-verbonden resources voldoen aan de basis governance-vereisten." -ForegroundColor Green } else { Write-Host "❌ NON-COMPLIANT - Eén of meer Arc-verbonden resources hebben governance-hiaten." -ForegroundColor Red Write-Host "Aanbevolen acties:" -ForegroundColor Yellow foreach ($rec in $result.Recommendations) { Write-Host (" - {0}" -f $rec) -ForegroundColor Yellow } } return $result } function Invoke-Remediation { <# .SYNOPSIS Geeft een remediatie-overzicht voor Arc-resources met governance-hiaten. #> [CmdletBinding()] param() Write-Host "`nRemediatie: $PolicyName" -ForegroundColor Yellow Write-Host "==============================================================" -ForegroundColor Yellow $result = Test-Compliance $allNonCompliant = @() $allNonCompliant += $result.Servers | Where-Object { $_.HasGovernanceIssues } $allNonCompliant += $result.Kubernetes | Where-Object { $_.HasGovernanceIssues } $allNonCompliant += $result.DataServices | Where-Object { $_.HasGovernanceIssues } if ($allNonCompliant.Count -eq 0) { Write-Host "Alle Arc-verbonden resources voldoen aan de basis governance-vereisten. Geen remediatie nodig." -ForegroundColor Green return $result } Write-Host "`nNiet-conforme Arc-resources (met governance-hiaten):" -ForegroundColor Red foreach ($resource in $allNonCompliant) { $resourceType = switch -Regex ($resource.PSObject.Properties.Name) { "MachineName" { "Server" } "ClusterName" { "Kubernetes" } "ServiceName" { "Data Service" } default { "Unknown" } } Write-Host ("- Type: {0}" -f $resourceType) -ForegroundColor Red Write-Host (" Subscription: {0}" -f $resource.SubscriptionName) -ForegroundColor Red Write-Host (" ResourceGroup: {0}" -f $resource.ResourceGroupName) -ForegroundColor Red $resourceName = if ($resource.MachineName) { $resource.MachineName } elseif ($resource.ClusterName) { $resource.ClusterName } elseif ($resource.ServiceName) { $resource.ServiceName } else { "Unknown" } Write-Host (" Resource: {0}" -f $resourceName) -ForegroundColor Red Write-Host (" Locatie: {0}" -f $resource.Location) -ForegroundColor Red Write-Host " Geïdentificeerde issues:" -ForegroundColor Yellow foreach ($issue in $resource.GovernanceIssues) { Write-Host (" - {0}" -f $issue) -ForegroundColor Yellow } Write-Host "" } Write-Host "Aanbevolen vervolgstappen:" -ForegroundColor Yellow Write-Host "1. Vul ontbrekende kern-tags in (Owner, BusinessProcess, DataClassification) voor alle Arc-resources." -ForegroundColor Yellow Write-Host "2. Activeer Microsoft Defender-services voor Arc-enabled servers en Kubernetes-clusters." -ForegroundColor Yellow Write-Host "3. Installeer monitoring-agents (Log Analytics of Azure Monitor) op Arc-enabled servers." -ForegroundColor Yellow Write-Host "4. Implementeer Azure Policy voor Arc-resources om configuratiestandaarden af te dwingen." -ForegroundColor Yellow Write-Host "5. Configureer GitOps (Flux) voor Arc-enabled Kubernetes-clusters." -ForegroundColor Yellow Write-Host "6. Documenteer governance-afspraken en neem Arc-resources op in incidentresponsprocedures." -ForegroundColor Yellow Write-Host "7. Plan periodieke evaluaties van Arc-governance en veranker verbeteracties in de roadmap." -ForegroundColor Yellow if ($WhatIf) { Write-Host "`nWhatIf is ingeschakeld: er worden geen wijzigingen doorgevoerd; alleen een rapport is gegenereerd." -ForegroundColor Cyan } return $result } try { Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Script: azure-arc-overview" -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan Connect-RequiredServices if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { $result = Test-Compliance if ($result.IsCompliant) { Write-Host "`n✅ COMPLIANT" -ForegroundColor Green } else { Write-Host "`n❌ NON-COMPLIANT" -ForegroundColor Red Write-Host "`nRun met -Monitoring voor een gedetailleerd rapport" -ForegroundColor Yellow Write-Host "Run met -Remediation voor aanbevelingen" -ForegroundColor Yellow } return $result } } catch { Write-Error "Error: $_" throw } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan }

Risico zonder implementatie

Risico zonder implementatie
High: Wanneer servers, Kubernetes-clusters en databases die buiten Azure draaien zonder centrale governance worden beheerd, ontstaat een versnipperd landschap waarin beveiligingsconfiguraties inconsistent zijn, bedreigingen moeilijk zijn te detecteren, en compliance-rapportage gefragmenteerd blijft. Dit vergroot de kans op ernstige beveiligingsincidenten, niet-naleving van wet- en regelgeving en verlies van vertrouwen bij burgers en toezichthouders.

Management Samenvatting

Registreer kritieke hybride resources via Azure Arc, dwing beveiligings- en configuratiebeleid af met Azure Policy, activeer Microsoft Defender-services voor uniforme threat protection, en gebruik centrale rapportages om governance en compliance structureel te beheren. Het bijbehorende PowerShell-script helpt bij inventarisatie, monitoring en remediatie, zodat hybride beheer een aantoonbaar onderdeel wordt van de Nederlandse Baseline voor Veilige Cloud.