Created
May 15, 2022 13:49
-
-
Save KaiWalter/8dd1dfca55d81653fd50802ff0062c79 to your computer and use it in GitHub Desktop.
Private linking resources from inside an Azure VM to multiple regional networks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param ( | |
[Parameter(Mandatory)] | |
[ValidateSet( | |
"blob", | |
"configurationStores", | |
"namespace", | |
"registry", | |
"sites", | |
"Sql", | |
"sqlServer", | |
"table", | |
"vault" | |
)] | |
[string] | |
$GroupId, | |
[Parameter(Mandatory)] | |
[string] | |
$ResourceNamePattern, | |
[Parameter(Mandatory)] | |
[string] | |
$ResourceGroupNamePattern, | |
[switch] | |
$SkipDeletes, | |
[switch] | |
$SkipCreate | |
) | |
# -------------------------------------------------------------------------------- | |
# determine resource Ids | |
switch ($GroupId) { | |
"blob" { | |
$dnsZone = "privatelink.blob.core.windows.net" | |
$resourceType = "Microsoft.Storage/storageAccounts" | |
} | |
"configurationStores" { | |
$dnsZone = "privatelink.azconfig.io" | |
$resourceType = "Microsoft.AppConfiguration/configurationStores" | |
} | |
"namespace" { | |
$dnsZone = "privatelink.servicebus.windows.net" | |
$resourceType = "Microsoft.ServiceBus/namespaces" | |
} | |
"registry" { | |
$dnsZone = "privatelink.azurecr.io" | |
$resourceType = "Microsoft.ContainerRegistry/registries" | |
} | |
"sites" { | |
$dnsZone = "privatelink.azurewebsites.net" | |
$resourceType = "Microsoft.Web/sites" | |
} | |
"Sql" { | |
$dnsZone = "privatelink.documents.azure.com" | |
$resourceType = "Microsoft.AzureCosmosDB/databaseAccounts" | |
} | |
"sqlServer" { | |
$dnsZone = "privatelink.database.windows.net" | |
$resourceType = "Microsoft.Sql/servers" | |
} | |
"table" { | |
$dnsZone = "privatelink.table.core.windows.net" | |
$resourceType = "Microsoft.Storage/storageAccounts" | |
} | |
"vault" { | |
$dnsZone = "privatelink.vaultcore.azure.net" | |
$resourceType = "Microsoft.KeyVault/vaults" | |
} | |
} | |
$resources = @() | |
az resource list --resource-type $resourceType -o json | ConvertFrom-Json | ` | |
? { $_.name -match $ResourceNamePattern -and $_.resourceGroup -match $ResourceGroupNamePattern } | % { | |
$resources += @{id = $_.id; name = $_.name } | |
} | |
if ($resources.Count -eq 0) { | |
Write-Error "No resources found matching the pattern" | |
Exit | |
} | |
# -------------------------------------------------------------------------------- | |
# detect VM metadata | |
# see https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=windows | |
$vmInfo = Invoke-RestMethod -Headers @{"Metadata" = "true" } -Method GET -NoProxy -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | |
$nicId = az vm show --subscription $vmInfo.compute.subscriptionId --resource-group $vmInfo.compute.resourceGroupName --name $vmInfo.compute.name --query networkProfile.networkInterfaces[0].id --output tsv | |
$subnetId = az network nic show --ids $nicId --query ipConfigurations[0].subnet.id --output tsv | |
$vnetInfo = $subnetId.split('/')[0..8] | |
$vnetId = [string]::Join("/", $vnetInfo) | |
Write-Host "NIC :" $nicId | |
Write-Host "VNET :" $vnetId | |
Write-Host "SUBNET :" $subnetId | |
# -------------------------------------------------------------------------------- | |
if (!$SkipDeletes) { | |
Write-Host "delete existing (VM's) virtual network links" | |
az network vnet peering list --vnet-name $vnetInfo[8] -g $vnetInfo[4] --subscription $vnetInfo[2] --output json | ConvertFrom-Json | % { | |
az network vnet peering delete --ids $_.Id | |
} | |
Write-Host "delete existing (VM's) private endpoint links" | |
az network private-endpoint list -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId --output json | ConvertFrom-Json | % { | |
az network private-endpoint delete --ids $_.Id | |
} | |
Write-Host "delete existing (VM's) private DNS links" | |
if ($(az network private-dns zone list -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId --query "[?name == '$dnsZone'].id" -o tsv)) { | |
az network private-dns link vnet list -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId --zone-name $dnsZone -o json | ConvertFrom-Json | % { | |
if ($_.virtualNetwork.id -eq $vnetId) { | |
Write-Host "deleting link: $($_.id)" | |
az network private-dns link vnet delete -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId --zone-name $dnsZone --name $_.name --yes | |
} | |
} | |
} | |
} | |
if (!$SkipCreate) { | |
Write-Host "create/check private DNS zone" $dnsZone "for group" $groupId | |
if (!$(az network private-dns zone list -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId --query "[?name == '$dnsZone'].id" -o tsv)) { | |
az network private-dns zone create -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId ` | |
-n $dnsZone | |
} | |
Write-Host "create private DNS link" | |
az network private-dns link vnet create -g $vmInfo.compute.resourceGroupName --subscription $vmInfo.compute.subscriptionId ` | |
-n $("vnet-" + $groupId + "-dns-link") ` | |
-z $dnsZone -v $vnetId -e false | |
Write-Host "private link resources" | |
foreach ($resource in $resources) { | |
Write-Host "link" $resource.name | |
$linkName = $GroupId + "-" + $resource.name + "-" + $vmInfo.compute.name + "-link" | |
$endpointName = $GroupId + "-" + $resource.name + "-" + $vmInfo.compute.name + "-pep" | |
$groupName = $GroupId + "-" + $resource.name + "-" + $vmInfo.compute.name + "-zonegroup" | |
az network private-endpoint create --connection-name $linkName ` | |
--name $endpointName ` | |
-g $vmInfo.compute.resourceGroupName ` | |
--subscription $vmInfo.compute.subscriptionId ` | |
--private-connection-resource-id $resource.id ` | |
--group-id $GroupId ` | |
--subnet $subnetId | |
az network private-endpoint dns-zone-group create ` | |
-g $vmInfo.compute.resourceGroupName ` | |
--subscription $vmInfo.compute.subscriptionId ` | |
--endpoint-name $endpointName ` | |
--name $groupName ` | |
--private-dns-zone $dnsZone ` | |
--zone-name $dnsZone | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment