Skip to main content

Azure Region Provider Comparison

· 5 min read

With the release of the New Zealand North Azure Region on the horizon, I wanted a way to measure what capabilities are being deployed in the new region that could be used, particularly in comparison to Australia East.

To do so, I wrote a script that uses PowerShell to query the provider namespaces of each region, compare them side by side, and output the results into an HTML table.

Azure Region Provider Comparison

There are bound to be differences between the regions, especially when Strategic Services, such as Azure OpenAI (Cognitive Services), are involved, especially for such a new region, especially at the time of writing when not all Foundational and Mainstream services may have been deployed.

warning

Using the Providers is not a full-proof way of comparing the regions; however, for my purposes, it largely helps to identify the capabilities, especially when compared to the Azure services table. Its also worth mentioning, that this comparison won't touch on some services or capabilities, that may be may have preview capabilities delivered to specific regions as a sub-feature of that namespace.

The PowerShell script can be found below:

RegionProvider_Compare.ps1
# Get the current date in an easy-to-read format
$currentDate = Get-Date -Format "MMMM dd, yyyy"

[string]$location1 = "New Zealand North"
[string]$location2 = "Australia East"



function Get-ProviderNamespaces {
param (
[string]$location
)

# Validate location parameter
if (-not $location) {
throw "Location parameter is required."
}

try {
$providers = Get-AzResourceProvider
$providerNamespaces = @()

foreach ($provider in $providers) {
$providerNamespace = $provider.ProviderNamespace
$resourceTypes = $provider.ResourceTypes | Where-Object { $_.Locations -contains $location }

if ($resourceTypes) {
$providerNamespaces += $providerNamespace
}
}

return $providerNamespaces | Sort-Object -Unique
}
catch {
Write-Error "Failed to get provider namespaces for location $location : $_"
throw
}
}

function Create-ComparisonTable {
param (
[array]$providerNamespaces1,
[array]$providerNamespaces2
)
$table = @()
$maxLength = [math]::Max($providerNamespaces1.Count, $providerNamespaces2.Count)

for ($i = 0; $i -lt $maxLength; $i++) {
$provider1 = if ($i -lt $providerNamespaces1.Count) { $providerNamespaces1[$i] } else { "" }
$provider2 = if ($i -lt $providerNamespaces2.Count) { $providerNamespaces2[$i] } else { "" }
$missingInLocation1 = if ($provider2 -and -not $providerNamespaces1.Contains($provider2)) { $provider2.Trim() } else { "" }

if ($provider1 -or $provider2 -or $missingInLocation1) {
$table += [PSCustomObject]@{
"$location1 ($($providerNamespaces1.Count))" = $provider1
"$location2 ($($providerNamespaces2.Count))" = $provider2
"Missing in $location1" = $missingInLocation1
}
}
}

return $table
}

# Generate the HTML report with the date in the title
function Generate-HTMLReport {
param (
[array]$comparisonTable,
[string]$location1,
[string]$location2
)

$html = @"
<!DOCTYPE html>
<html>
<head>
<title>Azure Provider Namespaces Comparison - $currentDate</title>
<style>
table {
width: 100%;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin: 20px 0;
border-radius: 5px 5px 0 0;
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
th, td {
padding: 12px 15px;
text-align: left;
}
th {
text-transform: uppercase;
font-weight: bold;
}
th:nth-child(1) {
background-color: #4CAF50;
color: white;
}
th:nth-child(2) {
background-color: #2196F3;
color: white;
}
th:nth-child(3) {
background-color: #FF9800;
color: white;
}
tr {
border-bottom: 1px solid #dddddd;
}
tr:nth-child(even) {
background-color: #f3f3f3;
}
tr:last-child {
border-bottom: 2px solid #009879;
}
tr:hover {
background-color: #f1f1f1;
}
</style>
</head>
<body>
<h1>Azure Provider Namespaces Comparison</h1>
<p>Comparison of <a href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-services-resource-providers?WT.mc_id=AZ-MVP-5004796">provider namespaces</a> between <strong>$location1</strong> and <strong>$location2</strong> as of $currentDate.</p>
<table>
<tr>
<th>$location1 ($($providerNamespaces1.Count))</th>
<th>$location2 ($($providerNamespaces2.Count))</th>
<th>Missing in $location1</th>
</tr>
"@

foreach ($row in $comparisonTable) {
$html += "<tr>"
$html += "<td>$($row."$location1 ($($providerNamespaces1.Count))")</td>"
$html += "<td>$($row."$location2 ($($providerNamespaces2.Count))")</td>"
$html += "<td>$($row."Missing in $location1")</td>"
$html += "</tr>"
}

$html += @"
</table>
<h2>Service Categories</h2>
<ul>
<li><strong><a href="https://learn.microsoft.com/azure/reliability/availability-service-by-category?WT.mc_id=AZ-MVP-5004796#available-services-by-region-category">Foundational</a></strong>: Available in all recommended and alternate regions when the region is generally available, or within 90 days of a new foundational service becoming generally available.</li>
<li><strong><a href="https://learn.microsoft.com/azure/reliability/availability-service-by-category?WT.mc_id=AZ-MVP-5004796#available-services-by-region-category">Mainstream</a></strong>: Available in all recommended regions within 90 days of the region general availability. Demand-driven in alternate regions, and many are already deployed into a large subset of alternate regions.</li>
<li><strong><a href="https://learn.microsoft.com/azure/reliability/availability-service-by-category?WT.mc_id=AZ-MVP-5004796#strategic-services">Strategic</a></strong>: Targeted service offerings, often industry-focused or backed by customized hardware. Demand-driven availability across regions.</li>
</ul>
<p>Note: The rollout schedule for services may vary based on their category and region, with Foundational Services being prioritized for early adoption, followed by Mainstream services (+90 days after GA), and finally Strategic services as demand requirements. Make sure you let your Microsoft account team know if a Strategic Service is required in your region.</p>
</body>
</html>
"@

return $html
}

# Main script execution
try {
Write-Host "Fetching provider namespaces for $location1 and $location2 ..." -ForegroundColor Green

$providerNamespaces1 = Get-ProviderNamespaces -location $location1
$providerNamespaces2 = Get-ProviderNamespaces -location $location2

$comparisonTable = Create-ComparisonTable -providerNamespaces1 $providerNamespaces1 -providerNamespaces2 $providerNamespaces2

Write-Host "Generating HTML report..." -ForegroundColor Green
$htmlReport = Generate-HTMLReport -comparisonTable $comparisonTable -location1 $location1 -location2 $location2

$reportPath = "AzureProviderComparisonReport.html"
$htmlReport | Out-File -FilePath $reportPath

Write-Host "HTML report generated at $reportPath" -ForegroundColor Green
}
catch {
Write-Error "An error occurred: $_"
}

It will output an HTML report in the directory that the script has been run from (make sure you are authenticated to Azure first and have the Az PowerShell modules installed):

Azure Region Provider Comparison