added documetation

This commit is contained in:
Jurjen Ladenius
2025-11-03 08:12:01 +01:00
parent 8840b0e300
commit a226ca97ac
37 changed files with 8315 additions and 1481 deletions

View File

@@ -1,77 +1,461 @@
# .\FrontDoorRoutes.ps1 -SubscriptionId "4820b5d8-cc1d-49bd-93e5-0c7a656371b7" -ResourceGroupName "my-effectory-global" -FrontDoorName "my-effectory-frontDoor"
<#
.SYNOPSIS
Exports Azure Front Door route configuration and origin mappings to a CSV file.
.DESCRIPTION
This script retrieves and documents the complete routing configuration for an Azure Front Door
(Standard/Premium) CDN profile. It extracts detailed information about endpoints, routes,
route patterns, origin groups, and individual origins, providing a comprehensive view of
traffic routing and backend configurations.
The script is designed for:
- Front Door configuration documentation and auditing
- Traffic routing analysis and optimization
- Origin backend inventory and health monitoring
- Troubleshooting routing issues and misconfigurations
- Migration planning and configuration validation
- Compliance documentation for CDN configurations
Key features:
- Complete route topology mapping from endpoints to backends
- Pattern matching rules documentation
- Origin health and enabled state tracking
- Route enablement status monitoring
- Structured CSV export for analysis and reporting
The exported data includes full URL construction for both front-end endpoints and
backend origins, making it easy to understand the complete request flow through
the Front Door configuration.
.PARAMETER SubscriptionId
The Azure subscription ID containing the Front Door profile.
This parameter is optional - if not provided, the script will use the current
subscription context. Must be a valid GUID format.
Example: "4820b5d8-cc1d-49bd-93e5-0c7a656371b7"
.PARAMETER ResourceGroupName
The name of the resource group containing the Front Door profile.
This parameter is mandatory and is case-sensitive.
Example: "my-effectory-global"
.PARAMETER FrontDoorName
The name of the Azure Front Door (Standard/Premium) profile to analyze.
This parameter is mandatory and is case-sensitive. Must be a valid Front Door
profile name (not the legacy Front Door Classic).
Example: "my-effectory-frontDoor"
.EXAMPLE
.\FrontDoorRoutes.ps1 -SubscriptionId "4820b5d8-cc1d-49bd-93e5-0c7a656371b7" -ResourceGroupName "my-effectory-global" -FrontDoorName "my-effectory-frontDoor"
Exports all route configurations for the specified Front Door profile with explicit subscription targeting.
.EXAMPLE
.\FrontDoorRoutes.ps1 -ResourceGroupName "production-rg" -FrontDoorName "prod-frontdoor"
Exports route configurations using the current subscription context.
.EXAMPLE
# Analyze multiple Front Door profiles
$frontDoors = @("frontdoor1", "frontdoor2", "frontdoor3")
foreach ($fd in $frontDoors) {
.\FrontDoorRoutes.ps1 -ResourceGroupName "global-rg" -FrontDoorName $fd
}
Batch processes multiple Front Door profiles for comprehensive documentation.
.EXAMPLE
# Export and immediately analyze results
.\FrontDoorRoutes.ps1 -ResourceGroupName "my-rg" -FrontDoorName "my-frontdoor"
$results = Import-Csv ".\$(Get-Date -Format 'yyyy-MM-dd HHmm') Front Door Routes (my-frontdoor).csv"
$results | Where-Object RouteEnabled -eq "Disabled" | Format-Table
Exports configuration and immediately identifies disabled routes for analysis.
.NOTES
Author: Cloud Engineering Team
Version: 1.0
Prerequisites:
- Azure PowerShell module (Az) must be installed
- Az.Cdn module specifically required for Front Door operations
- User must be authenticated to Azure (Connect-AzAccount)
- User must have at least 'Reader' permissions on the Front Door profile
Required Permissions:
- Reader access to the subscription and resource group
- CDN Profile Reader or Contributor permissions on the Front Door profile
- Access to Front Door endpoints, routes, and origin groups
Front Door Compatibility:
- Supports Azure Front Door Standard and Premium profiles
- Does NOT support legacy Azure Front Door Classic (different API)
- Requires Front Door profile to be in Standard or Premium tier
Output File:
- Format: "YYYY-MM-DD HHMM Front Door Routes ({FrontDoorName}).csv"
- Location: Current directory
- Content: Complete route topology with origins and patterns
CSV Structure:
- FrontDoorName: Front Door profile name
- EndpointName: Front Door endpoint name
- RouteName: Individual route configuration name
- RoutePatterns: URL patterns matched by this route (semicolon-separated)
- RouteUrl: Complete front-end URL for the endpoint
- OriginGroupName: Backend origin group name
- OriginName: Individual origin/backend name
- OriginUrl: Backend origin hostname/URL
- OriginEnabled: Origin availability status
- RouteEnabled: Route activation status
Performance Considerations:
- Processing time depends on the number of endpoints and routes
- Large Front Door configurations may require extended execution time
- Network latency affects configuration retrieval speed
Troubleshooting Notes:
- Ensure Front Door is Standard/Premium (not Classic)
- Verify resource group and Front Door names are correct
- Check that all required Az modules are installed and updated
- Confirm appropriate permissions on the Front Door resource
.LINK
https://docs.microsoft.com/en-us/azure/frontdoor/
https://docs.microsoft.com/en-us/powershell/module/az.cdn/
#>
param(
[Parameter(Mandatory=$false)]
[Parameter(Mandatory = $false, HelpMessage = "Azure subscription ID (optional - uses current context if not specified)")]
[ValidateScript({
if ([string]::IsNullOrEmpty($_) -or ($_ -match '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$')) {
$true
} else {
throw "Subscription ID must be a valid GUID format"
}
})]
[string]$SubscriptionId,
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true, HelpMessage = "Resource group name containing the Front Door profile")]
[ValidateNotNullOrEmpty()]
[ValidateLength(1, 90)]
[string]$ResourceGroupName,
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true, HelpMessage = "Front Door profile name (Standard/Premium)")]
[ValidateNotNullOrEmpty()]
[ValidateLength(1, 260)]
[string]$FrontDoorName
)
[string] $date = Get-Date -Format "yyyy-MM-dd HHmm"
$fileName = ".\$date Front Door Routes ($FrontDoorName).csv"
# Connect to Azure if not already connected
if (-not (Get-AzContext)) {
Connect-AzAccount
}
# Select subscription if provided
# Display script header and configuration
Write-Host "======================================================================================================================================================================"
Write-Host "Azure Front Door Route Configuration Export"
Write-Host "======================================================================================================================================================================"
Write-Host "Front Door Profile: $FrontDoorName"
Write-Host "Resource Group: $ResourceGroupName"
if ($SubscriptionId) {
Select-AzSubscription -SubscriptionId $SubscriptionId
Write-Host "Selected subscription: $SubscriptionId" -ForegroundColor Yellow
Write-Host "Target Subscription: $SubscriptionId"
} else {
Write-Host "Using current subscription context"
}
Write-Host "Script execution started: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Host "======================================================================================================================================================================"
Write-Host ""
# Generate timestamped filename for export
[string] $date = Get-Date -Format "yyyy-MM-dd HHmm"
$fileName = ".\$date Front Door Routes ($FrontDoorName).csv"
Write-Host "Export file: $fileName"
Write-Host ""
# Ensure Azure authentication
Write-Host "Verifying Azure authentication..."
if (-not (Get-AzContext)) {
Write-Host "No Azure context found. Initiating authentication..."
try {
Connect-AzAccount -ErrorAction Stop
Write-Host "✓ Successfully authenticated to Azure"
} catch {
Write-Error "Failed to authenticate to Azure. Please run Connect-AzAccount manually."
throw $_
}
} else {
Write-Host "✓ Azure authentication verified"
}
# Set target subscription if provided
if ($SubscriptionId) {
Write-Host "Setting subscription context..."
try {
$context = Select-AzSubscription -SubscriptionId $SubscriptionId -ErrorAction Stop
Write-Host "✓ Successfully connected to subscription: $($context.Subscription.Name)" -ForegroundColor Green
} catch {
Write-Error "Failed to select subscription: $SubscriptionId"
Write-Error "Please verify the subscription ID and ensure you have access"
throw $_
}
} else {
$currentContext = Get-AzContext
Write-Host "✓ Using current subscription: $($currentContext.Subscription.Name)" -ForegroundColor Green
}
Write-Host ""
Write-Host "======================================================================================================================================================================"
Write-Host "Retrieving Front Door Configuration"
Write-Host "======================================================================================================================================================================"
try {
# Get Front Door profile
$frontDoor = Get-AzFrontDoorCdnProfile -ResourceGroupName $ResourceGroupName -Name $FrontDoorName
# Get Front Door profile and validate existence
Write-Host "Accessing Front Door profile '$FrontDoorName'..."
$frontDoor = Get-AzFrontDoorCdnProfile -ResourceGroupName $ResourceGroupName -Name $FrontDoorName -ErrorAction Stop
if (-not $frontDoor) {
Write-Error "Front Door '$FrontDoorName' not found in resource group '$ResourceGroupName'"
Write-Error "Front Door profile '$FrontDoorName' not found in resource group '$ResourceGroupName'"
Write-Error "Please verify the Front Door name and resource group are correct"
return
}
Write-Host "✓ Successfully accessed Front Door profile: $($frontDoor.Name)"
Write-Host " Profile Type: $($frontDoor.Sku.Name)"
Write-Host " Profile State: $($frontDoor.FrontDoorId)"
Write-Host ""
# Get all endpoints
$endpoints = Get-AzFrontDoorCdnEndpoint -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName
# Get all endpoints for the Front Door profile
Write-Host "Discovering Front Door endpoints..."
$endpoints = Get-AzFrontDoorCdnEndpoint -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -ErrorAction Stop
$routeData = @()
foreach ($endpoint in $endpoints) {
# Get routes for each endpoint
$routes = Get-AzFrontDoorCdnRoute -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -EndpointName $endpoint.Name
foreach ($route in $routes) {
# Get origin group details
$originGroupId = $route.OriginGroupId
$originGroupName = ($originGroupId -split '/')[-1]
$origins = Get-AzFrontDoorCdnOrigin -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -OriginGroupName $originGroupName
foreach ($origin in $origins) {
$routeData += [PSCustomObject]@{
FrontDoorName = $FrontDoorName
EndpointName = $endpoint.Name
RouteName = $route.Name
RoutePatterns = ($route.PatternsToMatch -join '; ')
RouteUrl = "https://$($endpoint.HostName)"
OriginGroupName = $originGroupName
OriginName = $origin.Name
OriginUrl = $origin.HostName
OriginEnabled = $origin.EnabledState
RouteEnabled = $route.EnabledState
}
}
}
if (-not $endpoints -or $endpoints.Count -eq 0) {
Write-Warning "No endpoints found for Front Door profile '$FrontDoorName'"
Write-Host "This Front Door profile may not have any configured endpoints."
return
}
# Export to CSV
Write-Host "Exporting Front Door routes to: $fileName" -ForegroundColor Green
$routeData | Export-Csv -Path $fileName -NoTypeInformation -Force
Write-Host "✓ Found $($endpoints.Count) endpoint(s):"
foreach ($endpoint in $endpoints) {
Write-Host " - $($endpoint.Name) (https://$($endpoint.HostName))"
}
Write-Host ""
# Initialize collection for route data and processing counters
$routeData = @()
$totalRoutes = 0
$totalOrigins = 0
$enabledRoutes = 0
$disabledRoutes = 0
$enabledOrigins = 0
$disabledOrigins = 0
Write-Host "Processing endpoints and route configurations..."
Write-Host ""
# Process each endpoint to extract route and origin information
foreach ($endpoint in $endpoints) {
Write-Host "Processing endpoint: $($endpoint.Name)"
Write-Host " Endpoint URL: https://$($endpoint.HostName)"
try {
# Get all routes configured for this endpoint
$routes = Get-AzFrontDoorCdnRoute -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -EndpointName $endpoint.Name -ErrorAction Stop
if (-not $routes -or $routes.Count -eq 0) {
Write-Host " ⚠ No routes found for this endpoint" -ForegroundColor Yellow
continue
}
Write-Host " ✓ Found $($routes.Count) route(s) for endpoint"
# Process each route in the endpoint
foreach ($route in $routes) {
Write-Host " Processing route: $($route.Name)"
Write-Host " Patterns: $($route.PatternsToMatch -join ', ')"
Write-Host " Status: $($route.EnabledState)"
# Track route statistics
$totalRoutes++
if ($route.EnabledState -eq "Enabled") {
$enabledRoutes++
} else {
$disabledRoutes++
}
try {
# Extract origin group information from route
$originGroupId = $route.OriginGroupId
$originGroupName = ($originGroupId -split '/')[-1]
Write-Host " Origin Group: $originGroupName"
# Get all origins in the origin group
$origins = Get-AzFrontDoorCdnOrigin -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -OriginGroupName $originGroupName -ErrorAction Stop
if (-not $origins -or $origins.Count -eq 0) {
Write-Host " ⚠ No origins found in origin group '$originGroupName'" -ForegroundColor Yellow
# Create entry even if no origins found
$routeData += [PSCustomObject]@{
FrontDoorName = $FrontDoorName
EndpointName = $endpoint.Name
RouteName = $route.Name
RoutePatterns = ($route.PatternsToMatch -join '; ')
RouteUrl = "https://$($endpoint.HostName)"
OriginGroupName = $originGroupName
OriginName = "No origins found"
OriginUrl = "N/A"
OriginEnabled = "N/A"
RouteEnabled = $route.EnabledState
}
continue
}
Write-Host " ✓ Found $($origins.Count) origin(s) in group"
# Process each origin in the origin group
foreach ($origin in $origins) {
Write-Host " Origin: $($origin.Name) -> $($origin.HostName) ($($origin.EnabledState))"
# Track origin statistics
$totalOrigins++
if ($origin.EnabledState -eq "Enabled") {
$enabledOrigins++
} else {
$disabledOrigins++
}
# Create structured data entry for CSV export
$routeData += [PSCustomObject]@{
FrontDoorName = $FrontDoorName
EndpointName = $endpoint.Name
RouteName = $route.Name
RoutePatterns = ($route.PatternsToMatch -join '; ')
RouteUrl = "https://$($endpoint.HostName)"
OriginGroupName = $originGroupName
OriginName = $origin.Name
OriginUrl = $origin.HostName
OriginEnabled = $origin.EnabledState
RouteEnabled = $route.EnabledState
}
}
} catch {
Write-Host " ❌ Error processing origin group: $($_.Exception.Message)" -ForegroundColor Red
# Create error entry for troubleshooting
$routeData += [PSCustomObject]@{
FrontDoorName = $FrontDoorName
EndpointName = $endpoint.Name
RouteName = $route.Name
RoutePatterns = ($route.PatternsToMatch -join '; ')
RouteUrl = "https://$($endpoint.HostName)"
OriginGroupName = "Error retrieving"
OriginName = "Error"
OriginUrl = $_.Exception.Message
OriginEnabled = "Error"
RouteEnabled = $route.EnabledState
}
}
}
} catch {
Write-Host " ❌ Error processing routes for endpoint '$($endpoint.Name)': $($_.Exception.Message)" -ForegroundColor Red
}
Write-Host ""
}
Write-Host "======================================================================================================================================================================"
Write-Host "Exporting Results and Analysis"
Write-Host "======================================================================================================================================================================"
# Export route configuration to CSV file
Write-Host "Exporting Front Door route configuration to CSV..."
try {
$routeData | Export-Csv -Path $fileName -NoTypeInformation -Force
Write-Host "✓ Successfully exported $($routeData.Count) route entries to: $fileName" -ForegroundColor Green
} catch {
Write-Error "Failed to export route data to CSV: $($_.Exception.Message)"
throw $_
}
# Display configuration summary table
Write-Host ""
Write-Host "Front Door Route Configuration Summary:"
Write-Host "======================================================================================================================================================================"
$routeData | Format-Table -Property FrontDoorName, EndpointName, RouteName, RoutePatterns, OriginGroupName, OriginName, RouteEnabled, OriginEnabled -AutoSize
# Generate detailed analysis and statistics
Write-Host ""
Write-Host "======================================================================================================================================================================"
Write-Host "Configuration Analysis Summary"
Write-Host "======================================================================================================================================================================"
Write-Host "Export completed: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Host ""
Write-Host "Front Door Statistics:"
Write-Host " Profile Name: $FrontDoorName"
Write-Host " Profile Type: $($frontDoor.Sku.Name)"
Write-Host " Total Endpoints: $($endpoints.Count)"
Write-Host " Total Routes: $totalRoutes"
Write-Host " Total Origins: $totalOrigins"
Write-Host ""
# Analyze route and origin health status
Write-Host "Route Status Analysis:"
Write-Host " ✓ Enabled Routes: $enabledRoutes"
Write-Host " ❌ Disabled Routes: $disabledRoutes"
Write-Host ""
Write-Host "Origin Status Analysis:"
Write-Host " ✓ Enabled Origins: $enabledOrigins"
Write-Host " ❌ Disabled Origins: $disabledOrigins"
Write-Host ""
# Identify potential issues
$issuesFound = @()
if ($disabledRoutes -gt 0) {
$issuesFound += "Some routes are disabled"
}
if ($disabledOrigins -gt 0) {
$issuesFound += "Some origins are disabled"
}
$errorEntries = $routeData | Where-Object { $_.OriginName -eq "Error" }
if ($errorEntries.Count -gt 0) {
$issuesFound += "Configuration retrieval errors detected"
}
if ($issuesFound.Count -gt 0) {
Write-Host "⚠ ATTENTION REQUIRED:"
foreach ($issue in $issuesFound) {
Write-Host " - $issue" -ForegroundColor Yellow
}
Write-Host " Review the CSV file for detailed information on affected routes/origins"
} else {
Write-Host "✓ All routes and origins are enabled and accessible"
}
Write-Host ""
Write-Host "Output File Information:"
Write-Host " File Path: $fileName"
Write-Host " File Size: $([Math]::Round((Get-Item $fileName).Length / 1KB, 2)) KB"
Write-Host " Records Exported: $($routeData.Count)"
Write-Host ""
Write-Host "Recommendations:"
Write-Host " - Review disabled routes and origins for intentional configuration"
Write-Host " - Validate routing patterns match expected traffic flow"
Write-Host " - Monitor origin health and performance regularly"
Write-Host " - Document configuration changes for audit trails"
Write-Host "======================================================================================================================================================================"
} catch {
Write-Error "Error retrieving Front Door routes: $($_.Exception.Message)"
Write-Host ""
Write-Host "======================================================================================================================================================================"
Write-Host "❌ ERROR OCCURRED DURING PROCESSING"
Write-Host "======================================================================================================================================================================"
Write-Error "Error retrieving Front Door route configuration: $($_.Exception.Message)"
Write-Host ""
Write-Host "Troubleshooting Steps:"
Write-Host " 1. Verify Front Door profile name and resource group are correct"
Write-Host " 2. ensure the Front Door is Standard or Premium (not Classic)"
Write-Host " 3. Check that you have appropriate permissions on the Front Door resource"
Write-Host " 4. Confirm the Az.Cdn PowerShell module is installed and up to date"
Write-Host " 5. Verify network connectivity to Azure services"
Write-Host "======================================================================================================================================================================"
throw $_
}