Azure Private Endpoints: Services En Configuratieoverzicht

💼 Management Samenvatting

Azure Private Endpoints bieden netwerkisolatie voor een breed scala aan Platform-as-a-Service (PaaS) diensten door deze diensten toegankelijk te maken via privé IP-adressen binnen een Virtual Network. Dit artikel biedt een uitgebreid overzicht van welke Azure-services Private Endpoints ondersteunen, welke subresources moeten worden geconfigureerd, en hoe deze configuraties effectief kunnen worden geïmplementeerd voor een complete Zero Trust-architectuur.

Aanbeveling
IMPLEMENTEER PRIVATE ENDPOINTS VOOR ALLE RELEVANTE AZURE-SERVICES
Risico zonder
High
Risk Score
9/10
Implementatie
60u (tech: 40u)
Van toepassing op:
Azure Storage Accounts
Azure SQL Database
Azure Key Vault
Azure Cosmos DB
Azure App Service
Azure Container Registry
Azure Cognitive Services
Azure Event Hubs
Azure Service Bus
Azure Machine Learning
Azure Data Factory
Azure Synapse Analytics
Azure Database for PostgreSQL
Azure Database for MySQL
Azure Database for MariaDB
Andere Azure PaaS Services

Het implementeren van Private Endpoints voor Azure PaaS-diensten is essentieel voor moderne cloudbeveiliging, maar niet alle Azure-services ondersteunen Private Endpoints op dezelfde manier. Sommige services vereisen specifieke subresource-configuraties, andere hebben verschillende Private DNS Zone-vereisten, en weer andere hebben specifieke tier-vereisten voor Private Endpoint-ondersteuning. Zonder een volledig overzicht van welke services Private Endpoints ondersteunen en hoe deze moeten worden geconfigureerd, kunnen organisaties onvolledige implementaties uitvoeren waarbij kritieke services onbeschermd blijven of verkeerde configuraties worden toegepast die leiden tot connectiviteitsproblemen. Bovendien veranderen de Private Endpoint-mogelijkheden regelmatig wanneer Microsoft nieuwe services toevoegt of bestaande services uitbreidt, waardoor het essentieel is om op de hoogte te blijven van de laatste ondersteuning. Dit artikel verschaft een complete gids voor het identificeren van alle relevante services binnen een Azure-omgeving, het bepalen welke Private Endpoint-configuraties nodig zijn, en het implementeren van consistente netwerkisolatie volgens best practices. Voor Nederlandse overheidsorganisaties is dit vooral belangrijk omdat NIS2 en BIO expliciet netwerkisolatie vereisen voor kritieke informatiesystemen, en zonder een complete implementatie kunnen compliance-hiaten ontstaan die leiden tot audit-bevindingen en mogelijke boetes.

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

Implementatie

Dit artikel biedt een uitgebreide gids voor het identificeren, configureren en implementeren van Private Endpoints voor alle relevante Azure PaaS-services. De eerste sectie behandelt een complete service-inventarisatie waarbij alle Azure-services worden geïdentificeerd die Private Endpoints ondersteunen, met gedetailleerde informatie over subresource-configuraties, Private DNS Zone-vereisten, en eventuele tier- of licentievereisten. De tweede sectie behandelt service-specifieke configuratievereisten, waarbij voor elke major service-categorie wordt uitgelegd welke subresources moeten worden geconfigureerd, welke DNS-zones nodig zijn, en welke specifieke overwegingen relevant zijn. De derde sectie beschrijft een gestructureerde implementatieaanpak waarbij services worden gegroepeerd op basis van implementatiecomplexiteit en prioriteit, met concrete implementatie-stappen per service-categorie. De vierde sectie behandelt geautomatiseerde validatie en monitoring, waarbij wordt uitgelegd hoe geautomatiseerde scripts kunnen worden gebruikt om te controleren welke services Private Endpoints hebben geconfigureerd en welke nog bescherming nodig hebben. De vijfde sectie behandelt best practices en veelvoorkomende valkuilen, waarbij wordt uitgelegd hoe configuratiefouten kunnen worden voorkomen en hoe optimale netwerkisolatie kan worden gerealiseerd. Het bijbehorende PowerShell-script automatiseert de inventarisatie van alle Azure-services die Private Endpoints kunnen gebruiken, identificeert services die nog Private Endpoints nodig hebben, valideert bestaande configuraties, en genereert implementatie-rapportages met concrete aanbevelingen per service-categorie.

Complete Service Inventarisatie: Welke Services Ondersteunen Private Endpoints

De eerste stap in het implementeren van Private Endpoints voor alle relevante Azure-services is het uitvoeren van een uitgebreide inventarisatie van alle PaaS-diensten binnen de Azure-omgeving en het identificeren van welke services Private Endpoint-ondersteuning bieden. Microsoft voegt regelmatig nieuwe services toe aan de lijst van Private Link-ondersteuning, en bestaande services krijgen soms aanvullende subresource-ondersteuning, waardoor het essentieel is om deze inventarisatie regelmatig uit te voeren. De inventarisatie moet zich richten op alle Platform-as-a-Service diensten die persoonsgegevens verwerken, kritieke bedrijfsfunctionaliteit leveren, of deel uitmaken van productie workloads. Dit omvat storage-services zoals Azure Storage Accounts (blob, file, queue, table storage), Azure Files en Azure Data Lake Storage Gen2, database-services zoals Azure SQL Database, SQL Managed Instance, Azure Database for PostgreSQL, Azure Database for MySQL, Azure Database for MariaDB, en Azure Cosmos DB met verschillende API-types, compute-services zoals Azure App Service (vereist Premium v2/v3 of Isolated tier), Azure Functions (vereist Premium of Dedicated tier), en Azure Container Instances, integration-services zoals Azure Service Bus, Azure Event Hubs, Azure Event Grid, Azure Logic Apps, en Azure API Management, data-services zoals Azure Data Factory, Azure Synapse Analytics, Azure Machine Learning, Azure Cognitive Services, en Azure Databricks, security-services zoals Azure Key Vault en Azure Active Directory Domain Services, developer-services zoals Azure Container Registry, Azure DevOps, en Azure Artifacts, en vele andere services die regelmatig worden gebruikt in moderne cloudomgevingen.

Voor elke geïdentificeerde service moet worden vastgesteld of Private Endpoint-ondersteuning beschikbaar is, welke subresources moeten worden geconfigureerd, en welke eventuele vereisten gelden. Azure Storage Accounts vereisen bijvoorbeeld aparte Private Endpoints voor elke storage-service: blob storage (subresource: blob), file storage (subresource: file), queue storage (subresource: queue), en table storage (subresource: table). Azure SQL Database gebruikt de subresource 'sqlServer' voor de logische SQL-server, terwijl SQL Managed Instance 'managedInstance' gebruikt. Azure Cosmos DB gebruikt verschillende subresources afhankelijk van het API-type: SQL API gebruikt 'Sql', MongoDB API gebruikt 'MongoDB', Cassandra API gebruikt 'Cassandra', Gremlin API gebruikt 'Gremlin', en Table API gebruikt 'Table'. Azure Key Vault gebruikt 'vault' als subresource, Azure App Service gebruikt 'sites' als subresource, Azure Container Registry gebruikt 'registry' als subresource, en Azure Event Hubs gebruikt 'namespace' als subresource. Deze subresource-specifieke configuraties zijn cruciaal omdat een Private Endpoint zonder de juiste subresource niet correct functioneert en de gewenste connectiviteit niet biedt.

Naast subresource-configuraties moeten ook Private DNS Zone-vereisten worden geïdentificeerd voor elke service-categorie. Azure Storage Accounts vereisen Private DNS Zones voor 'privatelink.blob.core.windows.net' (blob), 'privatelink.file.core.windows.net' (files), 'privatelink.queue.core.windows.net' (queue), en 'privatelink.table.core.windows.net' (table). Azure SQL Database vereist 'privatelink.database.windows.net', Azure Key Vault vereist 'privatelink.vaultcore.azure.net', Azure Cosmos DB vereist verschillende zones zoals 'privatelink.documents.azure.com' (SQL API) en 'privatelink.mongo.cosmos.azure.com' (MongoDB API), Azure App Service vereist 'privatelink.azurewebsites.net', Azure Container Registry vereist 'privatelink.azurecr.io', Azure Event Hubs vereist 'privatelink.servicebus.windows.net', Azure Service Bus vereist 'privatelink.servicebus.windows.net', en Azure Machine Learning vereist 'privatelink.api.azureml.ms' en 'privatelink.notebooks.azure.net'. Deze Private DNS Zones moeten worden gekoppeld aan het Virtual Network zodat automatische naamresolutie plaatsvindt, en zonder correcte DNS-configuratie kunnen applicaties nog steeds proberen verbinding te maken via publieke eindpunten ondanks de aanwezigheid van Private Endpoints.

Sommige services hebben specifieke tier- of licentievereisten voor Private Endpoint-ondersteuning. Azure App Service vereist Premium v2, Premium v3, of Isolated tier (Basic en Standard tiers ondersteunen geen Private Endpoints), Azure Functions vereist Premium of Dedicated (Consumption tier ondersteunt geen Private Endpoints), Azure Database for PostgreSQL vereist Single Server of Flexible Server deployment (Basic tier heeft beperkte Private Endpoint-ondersteuning), en Azure Cognitive Services heeft verschillende vereisten per service-type. Deze tier-vereisten moeten worden gecontroleerd voordat Private Endpoints worden geïmplementeerd, omdat pogingen om Private Endpoints te configureren voor services die deze niet ondersteunen zullen falen. Organisaties moeten ook overwegen of upgrades nodig zijn om Private Endpoint-ondersteuning te verkrijgen, en wat de kosten zijn van deze upgrades versus de beveiligingsvoordelen. Voor veel services zijn de kosten van Private Endpoints relatief laag (circa €6 per Private Endpoint per maand), maar tier-upgrades kunnen aanzienlijk duurder zijn en moeten zorgvuldig worden geëvalueerd in het licht van compliance-vereisten en beveiligingsbehoeften.

Service-specifieke Configuratievereisten en Best Practices

Elke Azure-service heeft specifieke configuratievereisten voor Private Endpoints die moeten worden begrepen en correct geïmplementeerd om optimale beveiliging en functionaliteit te garanderen. Storage-services vormen een van de meest complexe categorieën omdat Azure Storage Accounts meerdere subresources ondersteunen die elk een apart Private Endpoint vereisen. Voor een complete storage-accountbeveiliging moeten vier Private Endpoints worden geconfigureerd: één voor blob storage (subresource: blob), één voor file storage (subresource: file), één voor queue storage (subresource: queue), en één voor table storage (subresource: table). Elke subresource vereist zijn eigen Private DNS Zone, en alle vier de zones moeten worden gekoppeld aan het Virtual Network. Dit betekent dat voor een enkele storage-account acht configuratiestappen nodig zijn: vier Private Endpoints en vier Private DNS Zone-koppelingen. Het is cruciaal om alle vier de subresources te configureren, zelfs als de organisatie momenteel alleen blob storage gebruikt, omdat toekomstige gebruik van andere storage-types anders niet beschermd zou zijn. Daarnaast moet publieke blob-toegang worden uitgeschakeld via de 'AllowBlobPublicAccess' eigenschap, en moeten netwerkregels worden geconfigureerd om alleen toegang vanuit het Virtual Network toe te staan.

Database-services hebben andere configuratieoverwegingen. Azure SQL Database vereist een Private Endpoint met subresource 'sqlServer' die wordt gekoppeld aan de logische SQL-server, niet aan individuele databases. Dit betekent dat een enkele Private Endpoint alle databases op die SQL-server beschermt, wat efficiënter is dan per-database configuraties. SQL Managed Instance gebruikt echter 'managedInstance' als subresource en vereist een iets andere configuratie omdat Managed Instances al binnen een Virtual Network worden geplaatst. Azure Cosmos DB heeft de meest complexe configuratie omdat verschillende API-types verschillende subresources en DNS-zones vereisen. Een Cosmos DB-account met zowel SQL API als MongoDB API zou twee aparte Private Endpoints nodig hebben: één met subresource 'Sql' en één met subresource 'MongoDB'. Elke subresource heeft zijn eigen Private DNS Zone, en beide zones moeten worden gekoppeld aan het Virtual Network. Daarnaast moeten connection strings worden bijgewerkt om de private endpoints te gebruiken, en moet publieke netwerktoegang worden uitgeschakeld na verificatie van Private Endpoint-connectiviteit.

Compute-services zoals Azure App Service en Azure Functions hebben specifieke tier-vereisten die moeten worden overwogen. App Services vereisen Premium v2, Premium v3, of Isolated tier voor Private Endpoint-ondersteuning, wat betekent dat organisaties die Basic of Standard tiers gebruiken eerst moeten upgraden voordat Private Endpoints kunnen worden geïmplementeerd. Deze upgrades kunnen aanzienlijke kostenverhogingen met zich meebrengen (Premium v2 begint bij circa €150 per maand voor een kleine instance), en organisaties moeten deze kosten afwegen tegen de beveiligingsvoordelen en compliance-vereisten. Voor App Services moet het Private Endpoint worden gekoppeld aan een subnet dat is geconfigureerd met de juiste delegaties, en moet de Private DNS Zone 'privatelink.azurewebsites.net' worden geconfigureerd. Na implementatie van het Private Endpoint kan publieke netwerktoegang worden uitgeschakeld via de 'publicNetworkAccess' eigenschap, maar dit moet alleen worden gedaan na uitgebreide tests om te verifiëren dat alle applicaties correct functioneren via het Private Endpoint. Azure Functions hebben vergelijkbare vereisten, maar de implementatie is iets complexer omdat Functions vaak worden gebruikt in serverless-architecturen waarbij netwerkconfiguraties minder direct zijn.

Integration-services zoals Azure Service Bus, Azure Event Hubs, en Azure Event Grid hebben relatief eenvoudige Private Endpoint-configuraties maar vereisen zorgvuldige aandacht voor messaging-patronen en event-routing. Service Bus en Event Hubs gebruiken beide de Private DNS Zone 'privatelink.servicebus.windows.net', en beide gebruiken 'namespace' als subresource. Event Grid gebruikt 'topic' of 'domain' als subresource afhankelijk van het resource-type, en heeft zijn eigen Private DNS Zone 'privatelink.eventgrid.azure.net'. Voor deze services is het belangrijk om te overwegen dat Private Endpoints invloed kunnen hebben op publieke subscribers of publishers die toegang nodig hebben vanuit het internet. In sommige gevallen kunnen hybride configuraties nodig zijn waarbij zowel Private Endpoints als beperkte publieke toegang worden geconfigureerd, maar dit moet worden gedaan met strikte netwerkregels en firewall-configuraties. Azure Logic Apps hebben een specifieke configuratie waarbij Private Endpoints worden geconfigureerd voor de Logic App-resource zelf, en aanvullende overwegingen zijn nodig voor connectors die mogelijk externe services aanroepen. Azure API Management ondersteunt Private Endpoints voor zowel de management-endpoint als de gateway-endpoint, wat betekent dat meerdere Private Endpoints nodig kunnen zijn voor een complete implementatie.

Gebruik PowerShell-script private-endpoints-services.ps1 (functie Invoke-ServiceInventory) – Inventariseert alle Azure-services binnen het abonnement die Private Endpoints kunnen gebruiken, identificeert services die nog Private Endpoints nodig hebben, en genereert een implementatie-rapportage met concrete aanbevelingen per service-categorie..

Gestructureerde Implementatieaanpak: Prioritering en Faseplanning

Een succesvolle implementatie van Private Endpoints voor alle relevante Azure-services vereist een gestructureerde aanpak waarbij services worden gegroepeerd op basis van implementatiecomplexiteit, bedrijfskritiek, en compliance-vereisten. Een gefaseerde implementatie benadering helpt om risico's te minimaliseren, resources efficiënt te gebruiken, en voortgang te meten. De eerste fase zou moeten focussen op high-priority services die kritieke gegevens verwerken of die expliciet worden vereist door compliance-frameworks zoals NIS2 of BIO. Deze fase zou moeten omvatten: Azure Key Vault (beschermt geheimen en certificaten), Azure SQL Database en SQL Managed Instance (beschermt relationele databasegegevens), Azure Storage Accounts (beschermt blob- en file-data), en Azure Cosmos DB (beschermt NoSQL-databasegegevens). Deze services vormen de kern van de meeste Azure-implementaties en het beschermen ervan met Private Endpoints biedt de grootste beveiligingsimpact. De implementatie moet worden uitgevoerd tijdens geplande onderhoudsvensters om verstoringen te minimaliseren, en uitgebreide tests moeten worden uitgevoerd om te verifiëren dat alle applicaties correct functioneren via Private Endpoints voordat publieke toegang wordt uitgeschakeld.

De tweede fase zou moeten focussen op compute-services en integration-services die minder kritiek zijn maar nog steeds belangrijke beveiligingsvoordelen bieden. Deze fase zou moeten omvatten: Azure App Services (voor interne APIs en portals), Azure Functions (voor serverless workloads), Azure Container Registry (voor container-images), Azure Service Bus en Event Hubs (voor messaging), en Azure Logic Apps (voor workflow-automatisering). Voor sommige van deze services kunnen tier-upgrades nodig zijn voordat Private Endpoints kunnen worden geïmplementeerd, wat betekent dat kostenanalyses moeten worden uitgevoerd en budgetten moeten worden goedgekeurd. Organisaties moeten ook overwegen of alle App Services en Functions Private Endpoints nodig hebben, of alleen die welke interne diensten leveren. Public-facing applicaties hebben meestal geen Private Endpoints nodig maar moeten in plaats daarvan worden beschermd met Azure Application Gateway en Web Application Firewall. De implementatie moet worden voorafgegaan door een impactanalyse die identificeert welke applicaties en workflows worden beïnvloed, en communicatieplannen moeten stakeholders informeren over geplande wijzigingen en mogelijke impact.

De derde fase zou moeten focussen op data-services en AI-services die vaak minder kritiek zijn voor dagelijkse operaties maar die nog steeds gevoelige gegevens kunnen verwerken. Deze fase zou moeten omvatten: Azure Data Factory (voor ETL-workloads), Azure Synapse Analytics (voor data-warehouse-operaties), Azure Machine Learning (voor ML-workloads), Azure Cognitive Services (voor AI-functionaliteit), en Azure Databricks (voor big data-analyses). Deze services hebben vaak complexere configuraties omdat ze meerdere endpoints en subresources kunnen hebben, en ze kunnen afhankelijkheden hebben met andere services die ook Private Endpoints nodig hebben. Bijvoorbeeld, een Azure Data Factory-pipeline die data ophaalt uit een Azure Storage Account en deze laadt in Azure SQL Database zou Private Endpoints nodig hebben voor alle drie de services om volledige netwerkisolatie te garanderen. De implementatie moet zorgvuldig worden gepland om ervoor te zorgen dat alle afhankelijkheden correct worden geconfigureerd en dat pipelines blijven functioneren na de implementatie. Testomgevingen moeten worden gebruikt om complexe configuraties te valideren voordat productie-implementaties worden gestart.

Naast deze drie hoofd fasen moet er ook aandacht zijn voor continue monitoring en validatie. Na de implementatie van Private Endpoints voor alle services moet regelmatig worden gecontroleerd of nieuwe services worden toegevoegd aan de omgeving die ook Private Endpoints nodig hebben. Azure Policy kan worden gebruikt om automatisch te detecteren wanneer nieuwe PaaS-services worden gemaakt zonder Private Endpoints, en alertregels kunnen worden geconfigureerd om teams te waarschuwen wanneer services worden gedetecteerd die nog niet zijn beveiligd. Daarnaast moeten bestaande Private Endpoint-configuraties regelmatig worden gereviewd om te verifiëren dat ze nog steeds correct zijn geconfigureerd en dat er geen configuratiedrift heeft plaatsgevonden. Quarterly reviews moeten worden uitgevoerd waarbij alle PaaS-services worden geïnventariseerd, de Private Endpoint-status wordt gecontroleerd, en nieuwe services worden geïdentificeerd die bescherming nodig hebben. Deze continue aandacht voor Private Endpoint-configuraties zorgt ervoor dat de netwerkisolatie-updates blijven en dat nieuwe services automatisch worden beschermd volgens best practices.

Geautomatiseerde Validatie en Monitoring van Private Endpoint Configuraties

Geautomatiseerde validatie en monitoring zijn essentieel om te garanderen dat Private Endpoints correct zijn geconfigureerd voor alle relevante services en dat nieuwe services automatisch worden geïdentificeerd wanneer ze worden toegevoegd aan de omgeving. Het bijbehorende PowerShell-script automatiseert de inventarisatie van alle Azure-services die Private Endpoints kunnen gebruiken, identificeert services die nog Private Endpoints nodig hebben, valideert bestaande configuraties, en genereert implementatie-rapportages met concrete aanbevelingen per service-categorie. Het script doorzoekt het Azure-abonnement op alle relevante PaaS-services, controleert voor elke service of er een Private Endpoint is geconfigureerd met de juiste subresource, verifieert of Private DNS Zones correct zijn geconfigureerd, en controleert of publieke toegang is uitgeschakeld waar van toepassing. De resultaten worden gepresenteerd in een gestructureerd rapport dat per service-categorie aangeeft hoeveel services Private Endpoints hebben, hoeveel services nog bescherming nodig hebben, en welke specifieke configuratiestappen nodig zijn voor elke service.

Azure Policy kan worden gebruikt om compliance te automatiseren en te garanderen dat nieuwe services automatisch worden geconfigureerd met Private Endpoints wanneer dat mogelijk is. Policies kunnen worden gedefinieerd die vereisen dat specifieke service-types Private Endpoints hebben geconfigureerd voordat ze kunnen worden gebruikt in productieomgevingen, of die automatisch Private Endpoints aanmaken wanneer nieuwe services worden gemaakt. Deze policies kunnen worden toegepast op abonnements- of management group-niveau om ervoor te zorgen dat alle resources binnen de scope voldoen aan de gestelde eisen. Azure Policy biedt ook de mogelijkheid om automatische remediatie uit te voeren wanneer niet-compliant configuraties worden gedetecteerd, hoewel dit voor Private Endpoints moet worden gedaan met zorg omdat het configureren van Private Endpoints complex kan zijn en netwerkconfiguraties vereist. In plaats daarvan kunnen policies worden gebruikt om waarschuwingen te genereren wanneer services worden gedetecteerd die Private Endpoints missen, zodat IT-teams proactief kunnen reageren en de benodigde configuraties kunnen uitvoeren.

Monitoring en alerting moeten worden geconfigureerd om te detecteren wanneer services worden toegevoegd aan de omgeving die Private Endpoints nodig hebben, wanneer bestaande Private Endpoint-configuraties worden gewijzigd of verwijderd, en wanneer services publieke toegang hebben ingeschakeld ondanks de aanwezigheid van Private Endpoints. Azure Monitor kan worden gebruikt om query's uit te voeren op resource-inventarisaties, en Log Analytics-werkruimten kunnen worden gebruikt om trends te analyseren en waarschuwingen te configureren. De bijbehorende PowerShell-script kan worden geïntegreerd in Azure Automation-runbooks die regelmatig worden uitgevoerd om compliance-status te controleren en rapportages te genereren voor security- en compliance-teams. Deze geautomatiseerde aanpak vermindert de werklast voor IT-teams en zorgt voor consistente beveiliging, zelfs wanneer er frequente wijzigingen zijn aan de cloudomgeving. Daarnaast kunnen de rapportages worden gebruikt voor audit-doeleinden om aan te tonen dat organisaties proactief monitoren en handhaven dat alle relevante services Private Endpoints hebben geconfigureerd volgens best practices en compliance-vereisten.

Gebruik PowerShell-script private-endpoints-services.ps1 (functie Invoke-Monitoring) – Voert een read-only validatie uit van alle Azure-services die Private Endpoints kunnen gebruiken, controleert welke services Private Endpoints hebben geconfigureerd, en genereert een compliance-rapportage met concrete aanbevelingen..

Best Practices en Veelvoorkomende Valkuilen bij Private Endpoint Implementaties

Het implementeren van Private Endpoints voor Azure-services kan complex zijn, en er zijn verschillende veelvoorkomende valkuilen die kunnen leiden tot connectiviteitsproblemen, onvolledige beveiliging, of onnodige kosten. Een van de meest voorkomende fouten is het vergeten om alle subresources te configureren voor services die meerdere subresources ondersteunen. Azure Storage Accounts vereisen bijvoorbeeld vier aparte Private Endpoints (blob, file, queue, table), en organisaties die alleen blob storage gebruiken vergeten vaak om ook Private Endpoints te configureren voor de andere subresources. Dit creëert een beveiligingshiaat waarbij toekomstig gebruik van file, queue, of table storage niet beschermd zou zijn. De beste aanpak is om altijd alle beschikbare subresources te configureren, zelfs als ze momenteel niet worden gebruikt, om toekomstige beveiligingsproblemen te voorkomen. Daarnaast moeten organisaties regelmatig controleren of nieuwe subresources zijn toegevoegd aan services die ze gebruiken, en of deze nieuwe subresources ook Private Endpoints nodig hebben.

Een andere veelvoorkomende fout is het vergeten of onjuist configureren van Private DNS Zones. Private Endpoints zijn alleen effectief als DNS-resolutie correct werkt, en zonder juiste DNS-configuratie kunnen applicaties nog steeds proberen verbinding te maken via publieke eindpunten. Elke service-categorie heeft specifieke Private DNS Zone-vereisten, en deze zones moeten worden gekoppeld aan het Virtual Network waar de Private Endpoints zijn geconfigureerd. Organisaties vergeten vaak om Private DNS Zones te configureren, of ze configureren de zones maar koppelen ze niet aan de juiste Virtual Networks, waardoor DNS-resolutie niet werkt. De beste aanpak is om Private DNS Zones altijd te configureren als onderdeel van de Private Endpoint-implementatie, en om DNS-resolutie te testen vanaf virtuele machines binnen het Virtual Network om te verifiëren dat services correct worden omgezet naar private IP-adressen. Daarnaast moeten organisaties overwegen om Azure Private DNS-resolver te gebruiken voor complexe omgevingen met meerdere Virtual Networks of hybride connectiviteit, wat geavanceerde DNS-routing mogelijk maakt.

Het uitschakelen van publieke toegang voordat Private Endpoint-connectiviteit is geverifieerd is een kritieke fout die kan leiden tot service-onderbrekingen. Organisaties die haastig publieke toegang uitschakelen zonder eerst te testen of Private Endpoints correct functioneren, kunnen ontdekken dat applicaties niet meer werken en moeten dan snel publieke toegang weer inschakelen om service te herstellen. De beste aanpak is om eerst Private Endpoints te configureren en te verifiëren dat alle applicaties correct functioneren via private endpoints, en pas daarna publieke toegang uit te schakelen tijdens een gepland onderhoudsvenster. Uitgebreide tests moeten worden uitgevoerd die verschillende scenario's omvatten, waaronder normale werking, backup-operaties, monitoring-activiteiten, en disaster recovery-scenario's. Daarnaast moeten rollback-procedures worden gedocumenteerd voor het geval dat er onverwachte problemen optreden na het uitschakelen van publieke toegang, zodat snel kan worden gereageerd en service kan worden hersteld.

Kostenbeheer is ook een belangrijke overweging bij Private Endpoint-implementaties. Elke Private Endpoint kost circa €6 per maand, en voor services met meerdere subresources kunnen de kosten snel oplopen. Een Azure Storage Account met alle vier de subresources zou vier Private Endpoints vereisen, wat €24 per maand kost. Voor organisaties met tientallen of honderden services kunnen de totale kosten aanzienlijk zijn. Daarnaast kunnen tier-upgrades nodig zijn voor sommige services voordat Private Endpoints kunnen worden geïmplementeerd, wat extra kosten met zich meebrengt. Organisaties moeten een kostenanalyse uitvoeren voordat ze beginnen met implementaties, en moeten prioriteiten stellen op basis van bedrijfskritiek en compliance-vereisten. Services die niet-kritieke gegevens verwerken of die alleen worden gebruikt in ontwikkel- of testomgevingen hebben mogelijk geen Private Endpoints nodig, terwijl productie-services die gevoelige gegevens verwerken de hoogste prioriteit moeten krijgen. Daarnaast moeten organisaties regelmatig controleren of alle geconfigureerde Private Endpoints daadwerkelijk worden gebruikt, en moeten ongebruikte Private Endpoints worden verwijderd om kosten te besparen.

Documentatie en change management zijn cruciaal voor succesvolle Private Endpoint-implementaties. Alle Private Endpoint-configuraties moeten worden gedocumenteerd met informatie over welke services zijn beveiligd, welke subresources zijn geconfigureerd, welke Private DNS Zones zijn gebruikt, en welke Virtual Networks zijn betrokken. Deze documentatie moet worden bijgewerkt wanneer wijzigingen worden aangebracht, en moet beschikbaar zijn voor alle teamleden die betrokken zijn bij cloudbeheer. Change management-processen moeten worden gevolgd voor alle wijzigingen aan Private Endpoint-configuraties, en wijzigingen moeten worden getest in niet-productieomgevingen voordat ze worden toegepast op productie. Daarnaast moeten regelmatige reviews worden uitgevoerd om te verifiëren dat alle configuraties nog steeds correct zijn en dat er geen configuratiedrift heeft plaatsgevonden. Deze best practices helpen organisaties om succesvolle Private Endpoint-implementaties uit te voeren die optimale beveiliging bieden zonder onnodige complexiteit of kosten, en die voldoen aan moderne compliance-vereisten zoals NIS2 en BIO.

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 Azure Private Endpoints: Services en Configuratieoverzicht .DESCRIPTION Dit script ondersteunt Nederlandse overheidsorganisaties bij het inventariseren van alle Azure-services die Private Endpoints kunnen gebruiken, identificeert services die nog Private Endpoints nodig hebben, valideert bestaande configuraties, en genereert implementatie-rapportages met concrete aanbevelingen per service-categorie. Het script doorzoekt het Azure-abonnement op alle relevante PaaS-services, controleert voor elke service of er een Private Endpoint is geconfigureerd met de juiste subresource, verifieert of Private DNS Zones correct zijn geconfigureerd, en controleert of publieke toegang is uitgeschakeld waar van toepassing. .NOTES Filename: private-endpoints-services.ps1 Author: Nederlandse Baseline voor Veilige Cloud Created: 2025-01-20 Version: 1.0 Related JSON: content/azure/network/private-endpoints-services.json Category: network Workload: azure .LINK https://github.com/m365-tenant-best-practise .EXAMPLE .\private-endpoints-services.ps1 -Monitoring Voert een read-only inventarisatie uit van alle Azure-services die Private Endpoints kunnen gebruiken en toont een samenvatting van de huidige status. .EXAMPLE .\private-endpoints-services.ps1 -ServiceInventory Genereert een gedetailleerde inventarisatie van alle services die Private Endpoints ondersteunen, inclusief welke services nog bescherming nodig hebben. .EXAMPLE .\private-endpoints-services.ps1 -ExportPath .\private-endpoints-inventory.json Exporteert de inventarisatie- en aanbevelingsgegevens naar een JSON-bestand. #> #Requires -Version 5.1 #Requires -Modules Az.Accounts, Az.Network, Az.Resources, Az.Storage, Az.Sql, Az.KeyVault, Az.CosmosDB, Az.Websites, Az.ContainerRegistry [CmdletBinding()] param( [Parameter(HelpMessage = "Voer een read-only inventarisatie uit van alle Azure-services die Private Endpoints kunnen gebruiken")] [switch]$Monitoring, [Parameter(HelpMessage = "Genereer een gedetailleerde service-inventarisatie met configuratieaanbevelingen")] [switch]$ServiceInventory, [Parameter(HelpMessage = "Toon welke acties zouden worden uitgevoerd zonder deze echt uit te voeren")] [switch]$WhatIf, [Parameter(HelpMessage = "Optioneel pad om resultaten als JSON te exporteren")] [string]$ExportPath ) $ErrorActionPreference = 'Stop' # ============================================================================ # HEADER # ============================================================================ Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Azure Private Endpoints – Service Inventarisatie" -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan # ============================================================================ # HULPFUNCTIES # ============================================================================ function Connect-NbvvcAzContext { <# .SYNOPSIS Zorgt voor een geldige Az-context voor leesacties .DESCRIPTION Probeert eerst een bestaande context te gebruiken. Als er geen context is, wordt Connect-AzAccount aangeroepen. Dit is geschikt voor lokale debug- scenario's met een interactieve sessie of een managed identity. #> [CmdletBinding()] param() try { $context = Get-AzContext -ErrorAction SilentlyContinue if (-not $context) { Write-Host "Geen actieve Azure-context gevonden. Probeer te verbinden..." -ForegroundColor Yellow Connect-AzAccount -ErrorAction Stop | Out-Null $context = Get-AzContext -ErrorAction Stop } Write-Host "Actieve Azure-context: $($context.Subscription.Name) [$($context.Subscription.Id)]" -ForegroundColor Gray return $context } catch { Write-Host "[FAIL] Kon geen geldige Azure-context verkrijgen: $_" -ForegroundColor Red throw } } function Get-NbvvcPrivateEndpointSupportedServices { <# .SYNOPSIS Definieert alle Azure-services die Private Endpoints ondersteunen .OUTPUTS Hashtable met service-definities inclusief subresources en DNS-zones #> [CmdletBinding()] param() return @{ storage = @{ serviceType = "Storage Account" subresources = @("blob", "file", "queue", "table") dnsZones = @("privatelink.blob.core.windows.net", "privatelink.file.core.windows.net", "privatelink.queue.core.windows.net", "privatelink.table.core.windows.net") requiresTier = $false module = "Az.Storage" } sqlServer = @{ serviceType = "SQL Server" subresources = @("sqlServer") dnsZones = @("privatelink.database.windows.net") requiresTier = $false module = "Az.Sql" } keyVault = @{ serviceType = "Key Vault" subresources = @("vault") dnsZones = @("privatelink.vaultcore.azure.net") requiresTier = $false module = "Az.KeyVault" } cosmosDb = @{ serviceType = "Cosmos DB" subresources = @("Sql", "MongoDB", "Cassandra", "Gremlin", "Table") dnsZones = @("privatelink.documents.azure.com", "privatelink.mongo.cosmos.azure.com", "privatelink.cassandra.cosmos.azure.com", "privatelink.gremlin.cosmos.azure.com", "privatelink.table.cosmos.azure.com") requiresTier = $false module = "Az.CosmosDB" } appService = @{ serviceType = "App Service" subresources = @("sites") dnsZones = @("privatelink.azurewebsites.net") requiresTier = $true requiredTiers = @("PremiumV2", "PremiumV3", "Isolated") module = "Az.Websites" } containerRegistry = @{ serviceType = "Container Registry" subresources = @("registry") dnsZones = @("privatelink.azurecr.io") requiresTier = $false module = "Az.ContainerRegistry" } eventHubs = @{ serviceType = "Event Hubs" subresources = @("namespace") dnsZones = @("privatelink.servicebus.windows.net") requiresTier = $false module = "Az.EventHub" } serviceBus = @{ serviceType = "Service Bus" subresources = @("namespace") dnsZones = @("privatelink.servicebus.windows.net") requiresTier = $false module = "Az.ServiceBus" } } } function Invoke-ServiceInventory { <# .SYNOPSIS Inventariseert alle Azure-services die Private Endpoints kunnen gebruiken .OUTPUTS Hashtable met inventarisatie-resultaten per service-categorie #> [CmdletBinding()] param() Write-Host "`nInventarisatie van Azure-services die Private Endpoints kunnen gebruiken..." -ForegroundColor Yellow $inventory = @{ timestamp = Get-Date subscriptionId = (Get-AzContext).Subscription.Id services = @{} summary = @{ totalServices = 0 servicesWithPE = 0 servicesWithoutPE = 0 servicesNeedingTierUpgrade = 0 } } $supportedServices = Get-NbvvcPrivateEndpointSupportedServices # Storage Accounts Write-Host "`n Storage Accounts controleren..." -ForegroundColor Gray try { $storageAccounts = Get-AzStorageAccount -ErrorAction SilentlyContinue $storageInventory = @{ totalCount = $storageAccounts.Count withPE = @() withoutPE = @() } foreach ($sa in $storageAccounts) { $hasPE = $false $peConnections = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $sa.Id -ErrorAction SilentlyContinue $approvedPE = $peConnections | Where-Object { $_.PrivateLinkServiceConnectionState.Status -eq 'Approved' } if ($approvedPE) { $hasPE = $true $storageInventory.withPE += @{ name = $sa.StorageAccountName resourceGroup = $sa.ResourceGroupName id = $sa.Id } } else { $storageInventory.withoutPE += @{ name = $sa.StorageAccountName resourceGroup = $sa.ResourceGroupName id = $sa.Id } } } $inventory.services.storage = $storageInventory $inventory.summary.totalServices += $storageAccounts.Count $inventory.summary.servicesWithPE += $storageInventory.withPE.Count $inventory.summary.servicesWithoutPE += $storageInventory.withoutPE.Count Write-Host " Totaal: $($storageAccounts.Count), Met PE: $($storageInventory.withPE.Count), Zonder PE: $($storageInventory.withoutPE.Count)" -ForegroundColor $(if ($storageInventory.withoutPE.Count -eq 0) { "Green" } else { "Yellow" }) } catch { Write-Host " [WARN] Kon Storage Accounts niet volledig controleren: $_" -ForegroundColor Yellow } # SQL Servers Write-Host " SQL Servers controleren..." -ForegroundColor Gray try { $sqlServers = Get-AzSqlServer -ErrorAction SilentlyContinue $sqlInventory = @{ totalCount = $sqlServers.Count withPE = @() withoutPE = @() } foreach ($sql in $sqlServers) { $peConnections = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $sql.ResourceId -ErrorAction SilentlyContinue $approvedPE = $peConnections | Where-Object { $_.PrivateLinkServiceConnectionState.Status -eq 'Approved' } if ($approvedPE) { $sqlInventory.withPE += @{ name = $sql.ServerName resourceGroup = $sql.ResourceGroupName id = $sql.ResourceId } } else { $sqlInventory.withoutPE += @{ name = $sql.ServerName resourceGroup = $sql.ResourceGroupName id = $sql.ResourceId } } } $inventory.services.sqlServer = $sqlInventory $inventory.summary.totalServices += $sqlServers.Count $inventory.summary.servicesWithPE += $sqlInventory.withPE.Count $inventory.summary.servicesWithoutPE += $sqlInventory.withoutPE.Count Write-Host " Totaal: $($sqlServers.Count), Met PE: $($sqlInventory.withPE.Count), Zonder PE: $($sqlInventory.withoutPE.Count)" -ForegroundColor $(if ($sqlInventory.withoutPE.Count -eq 0) { "Green" } else { "Yellow" }) } catch { Write-Host " [WARN] Kon SQL Servers niet volledig controleren: $_" -ForegroundColor Yellow } # Key Vaults Write-Host " Key Vaults controleren..." -ForegroundColor Gray try { $keyVaults = Get-AzKeyVault -ErrorAction SilentlyContinue $kvInventory = @{ totalCount = $keyVaults.Count withPE = @() withoutPE = @() } foreach ($kv in $keyVaults) { $peConnections = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $kv.ResourceId -ErrorAction SilentlyContinue $approvedPE = $peConnections | Where-Object { $_.PrivateLinkServiceConnectionState.Status -eq 'Approved' } if ($approvedPE) { $kvInventory.withPE += @{ name = $kv.VaultName resourceGroup = $kv.ResourceGroupName id = $kv.ResourceId } } else { $kvInventory.withoutPE += @{ name = $kv.VaultName resourceGroup = $kv.ResourceGroupName id = $kv.ResourceId } } } $inventory.services.keyVault = $kvInventory $inventory.summary.totalServices += $keyVaults.Count $inventory.summary.servicesWithPE += $kvInventory.withPE.Count $inventory.summary.servicesWithoutPE += $kvInventory.withoutPE.Count Write-Host " Totaal: $($keyVaults.Count), Met PE: $($kvInventory.withPE.Count), Zonder PE: $($kvInventory.withoutPE.Count)" -ForegroundColor $(if ($kvInventory.withoutPE.Count -eq 0) { "Green" } else { "Yellow" }) } catch { Write-Host " [WARN] Kon Key Vaults niet volledig controleren: $_" -ForegroundColor Yellow } # Cosmos DB Accounts Write-Host " Cosmos DB Accounts controleren..." -ForegroundColor Gray try { $cosmosAccounts = Get-AzCosmosDBAccount -ErrorAction SilentlyContinue $cosmosInventory = @{ totalCount = $cosmosAccounts.Count withPE = @() withoutPE = @() } foreach ($cosmos in $cosmosAccounts) { $peConnections = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $cosmos.Id -ErrorAction SilentlyContinue $approvedPE = $peConnections | Where-Object { $_.PrivateLinkServiceConnectionState.Status -eq 'Approved' } if ($approvedPE) { $cosmosInventory.withPE += @{ name = $cosmos.Name resourceGroup = $cosmos.ResourceGroupName id = $cosmos.Id } } else { $cosmosInventory.withoutPE += @{ name = $cosmos.Name resourceGroup = $cosmos.ResourceGroupName id = $cosmos.Id } } } $inventory.services.cosmosDb = $cosmosInventory $inventory.summary.totalServices += $cosmosAccounts.Count $inventory.summary.servicesWithPE += $cosmosInventory.withPE.Count $inventory.summary.servicesWithoutPE += $cosmosInventory.withoutPE.Count Write-Host " Totaal: $($cosmosAccounts.Count), Met PE: $($cosmosInventory.withPE.Count), Zonder PE: $($cosmosInventory.withoutPE.Count)" -ForegroundColor $(if ($cosmosInventory.withoutPE.Count -eq 0) { "Green" } else { "Yellow" }) } catch { Write-Host " [WARN] Kon Cosmos DB Accounts niet volledig controleren: $_" -ForegroundColor Yellow } # App Services Write-Host " App Services controleren..." -ForegroundColor Gray try { $appServices = Get-AzWebApp -ErrorAction SilentlyContinue $appInventory = @{ totalCount = $appServices.Count withPE = @() withoutPE = @() needsUpgrade = @() } foreach ($app in $appServices) { $peConnections = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $app.Id -ErrorAction SilentlyContinue $approvedPE = $peConnections | Where-Object { $_.PrivateLinkServiceConnectionState.Status -eq 'Approved' } # Check if tier supports Private Endpoints $sku = $app.Sku $tierSupportsPE = $sku -match "Premium|Isolated" if ($approvedPE) { $appInventory.withPE += @{ name = $app.Name resourceGroup = $app.ResourceGroupName id = $app.Id } } elseif (-not $tierSupportsPE) { $appInventory.needsUpgrade += @{ name = $app.Name resourceGroup = $app.ResourceGroupName sku = $sku id = $app.Id } $inventory.summary.servicesNeedingTierUpgrade++ } else { $appInventory.withoutPE += @{ name = $app.Name resourceGroup = $app.ResourceGroupName id = $app.Id } } } $inventory.services.appService = $appInventory $inventory.summary.totalServices += $appServices.Count $inventory.summary.servicesWithPE += $appInventory.withPE.Count $inventory.summary.servicesWithoutPE += $appInventory.withoutPE.Count Write-Host " Totaal: $($appServices.Count), Met PE: $($appInventory.withPE.Count), Zonder PE: $($appInventory.withoutPE.Count), Upgrade nodig: $($appInventory.needsUpgrade.Count)" -ForegroundColor $(if ($appInventory.withoutPE.Count -eq 0 -and $appInventory.needsUpgrade.Count -eq 0) { "Green" } else { "Yellow" }) } catch { Write-Host " [WARN] Kon App Services niet volledig controleren: $_" -ForegroundColor Yellow } # Container Registries Write-Host " Container Registries controleren..." -ForegroundColor Gray try { $registries = Get-AzContainerRegistry -ErrorAction SilentlyContinue $registryInventory = @{ totalCount = $registries.Count withPE = @() withoutPE = @() } foreach ($reg in $registries) { $peConnections = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $reg.Id -ErrorAction SilentlyContinue $approvedPE = $peConnections | Where-Object { $_.PrivateLinkServiceConnectionState.Status -eq 'Approved' } if ($approvedPE) { $registryInventory.withPE += @{ name = $reg.Name resourceGroup = $reg.ResourceGroupName id = $reg.Id } } else { $registryInventory.withoutPE += @{ name = $reg.Name resourceGroup = $reg.ResourceGroupName id = $reg.Id } } } $inventory.services.containerRegistry = $registryInventory $inventory.summary.totalServices += $registries.Count $inventory.summary.servicesWithPE += $registryInventory.withPE.Count $inventory.summary.servicesWithoutPE += $registryInventory.withoutPE.Count Write-Host " Totaal: $($registries.Count), Met PE: $($registryInventory.withPE.Count), Zonder PE: $($registryInventory.withoutPE.Count)" -ForegroundColor $(if ($registryInventory.withoutPE.Count -eq 0) { "Green" } else { "Yellow" }) } catch { Write-Host " [WARN] Kon Container Registries niet volledig controleren: $_" -ForegroundColor Yellow } return $inventory } function Invoke-Monitoring { <# .SYNOPSIS Voert een read-only inventarisatie uit van alle Azure-services die Private Endpoints kunnen gebruiken .OUTPUTS Hashtable met inventarisatie-resultaten #> [CmdletBinding()] param() $null = Connect-NbvvcAzContext $inventory = Invoke-ServiceInventory Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "SAMENVATTING SERVICE INVENTARISATIE" -ForegroundColor Cyan Write-Host " Totaal services : $($inventory.summary.totalServices)" -ForegroundColor White Write-Host " Services met PE : $($inventory.summary.servicesWithPE)" -ForegroundColor Green Write-Host " Services zonder PE : $($inventory.summary.servicesWithoutPE)" -ForegroundColor $(if ($inventory.summary.servicesWithoutPE -gt 0) { "Red" } else { "Green" }) Write-Host " Services upgrade nodig : $($inventory.summary.servicesNeedingTierUpgrade)" -ForegroundColor $(if ($inventory.summary.servicesNeedingTierUpgrade -gt 0) { "Yellow" } else { "Gray" }) if ($inventory.summary.totalServices -gt 0) { $compliancePercentage = [math]::Round(($inventory.summary.servicesWithPE / $inventory.summary.totalServices) * 100, 1) Write-Host " Compliance percentage : $compliancePercentage%" -ForegroundColor $(if ($compliancePercentage -ge 90) { "Green" } elseif ($compliancePercentage -ge 70) { "Yellow" } else { "Red" }) } Write-Host "`n Per service-categorie:" -ForegroundColor Yellow foreach ($serviceCategory in $inventory.services.Keys) { $service = $inventory.services[$serviceCategory] if ($service.totalCount -gt 0) { $categoryCompliance = [math]::Round(($service.withPE.Count / $service.totalCount) * 100, 1) Write-Host " $($serviceCategory.ToUpper()): $($service.withPE.Count)/$($service.totalCount) met PE ($categoryCompliance%)" -ForegroundColor $(if ($categoryCompliance -ge 90) { "Green" } elseif ($categoryCompliance -ge 70) { "Yellow" } else { "Red" }) if ($service.withoutPE.Count -gt 0) { Write-Host " Services zonder PE:" -ForegroundColor Gray foreach ($item in $service.withoutPE) { Write-Host " - $($item.name) (RG: $($item.resourceGroup))" -ForegroundColor Gray } } } } if ($inventory.summary.servicesWithoutPE -gt 0) { Write-Host "`nAandachtspunten:" -ForegroundColor Yellow Write-Host " - $($inventory.summary.servicesWithoutPE) service(s) hebben nog Private Endpoints nodig" -ForegroundColor Yellow if ($inventory.summary.servicesNeedingTierUpgrade -gt 0) { Write-Host " - $($inventory.summary.servicesNeedingTierUpgrade) service(s) vereisen tier-upgrades voor Private Endpoint-ondersteuning" -ForegroundColor Yellow } Write-Host " Gebruik -ServiceInventory voor gedetailleerde aanbevelingen per service" -ForegroundColor Gray } else { Write-Host "`nGeen specifieke aandachtspunten gedetecteerd - alle services hebben Private Endpoints geconfigureerd." -ForegroundColor Green } return @{ inventory = $inventory } } # ============================================================================ # MAIN EXECUTION # ============================================================================ try { if ($ServiceInventory) { $null = Connect-NbvvcAzContext $inventory = Invoke-ServiceInventory Write-Host "`nGedetailleerde service-inventarisatie voltooid." -ForegroundColor Green Write-Host "Gebruik -ExportPath om resultaten naar JSON te exporteren." -ForegroundColor Gray if ($ExportPath) { $inventory | ConvertTo-Json -Depth 10 | Out-File -FilePath $ExportPath -Encoding UTF8 Write-Host "Inventarisatie geëxporteerd naar: $ExportPath" -ForegroundColor Green } } elseif ($Monitoring) { $result = Invoke-Monitoring if ($ExportPath) { $result.inventory | ConvertTo-Json -Depth 10 | Out-File -FilePath $ExportPath -Encoding UTF8 Write-Host "`nRapport geëxporteerd naar: $ExportPath" -ForegroundColor Green } } else { Write-Host "Beschikbare parameters:" -ForegroundColor Yellow Write-Host " -Monitoring : Voer een read-only inventarisatie uit van alle services" -ForegroundColor Gray Write-Host " -ServiceInventory : Genereer een gedetailleerde service-inventarisatie" -ForegroundColor Gray Write-Host " -ExportPath : Optioneel pad voor JSON-rapport" -ForegroundColor Gray Write-Host "`nVoorbeeld: .\private-endpoints-services.ps1 -Monitoring" -ForegroundColor Cyan } } catch { Write-Error "Scriptuitvoering mislukt: $_" exit 2 } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } # Exitcodes: # 0 = Succesvolle uitvoering # 2 = Fout tijdens uitvoering

Risico zonder implementatie

Risico zonder implementatie
High: Zonder een compleet overzicht en gestructureerde implementatie van Private Endpoints voor alle relevante Azure-services kunnen organisaties onvolledige beveiliging implementeren waarbij kritieke services onbeschermd blijven. Dit creëert compliance-hiaten met NIS2 en BIO, verhoogd risico op gegevensexfiltratie, en potentiële audit-bevindingen. Daarnaast kunnen verkeerde configuraties leiden tot connectiviteitsproblemen en onnodige kosten.

Management Samenvatting

Dit artikel biedt een uitgebreide gids voor het identificeren, configureren en implementeren van Private Endpoints voor alle relevante Azure PaaS-services. Het behandelt service-specifieke configuratievereisten, subresource-configuraties, Private DNS Zone-vereisten, en best practices voor een gestructureerde implementatie. Het bijbehorende PowerShell-script automatiseert de inventarisatie van alle Azure-services die Private Endpoints kunnen gebruiken, identificeert services die nog bescherming nodig hebben, en genereert implementatie-rapportages. Voldoet aan CIS 6.3-6.4, BIO 13.01/12.04, ISO 27001 A.8.20/A.8.15, NIS2 Artikel 21. Implementatietijd: 40 uur technisch + 20 uur voor governance en documentatie. CRITICAL voor complete netwerkisolatie van alle PaaS-services.