Azure VNet Peering across Azure Active Directory tenants using Service Principal authentication

Video Walkthrough

Tip: Play the video full screen.

Table of Contents

00:00 Beginning of video
01:07 Mark Azure AD app as “multi-tenanted”
04:05 Consent to the multi-tenanted app to create service principal in 2nd tenant
07:09 Assign Contributor permission to the service principal
09:20 Create VNet peering using Azure PowerShell
14:21 Login using Azure CLI to obtain access tokens
17:25 Create VNet peering using Azure Resource Manager API in Postman

Mark Azure AD Application as Multi-Tenanted

In the 1st Azure AD tenant, create Azure AD application and set its Settings->Properties for multi-tenanted = Yes.
Record application id (client_id) and key (client_secret).

Create Service Principal from Application

In the 2nd Azure AD tenant, consent to the multi-tenanted application so that corresponding Service Principal is created in the 2nd tenant.

https:// login.microsoftonline.com/TENANT2_ID/oauth2/authorize?client_id=CLIENT_ID_OF_MULTI_TENATED_APPLICATION&response_type=code&redirect_uri=http%3A%2F%2Fwww.microsoft.com%2F

Azure PowerShell Example

$applicationId = "CLIENT_ID"
$key = "CLIENT_SECRET| ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object -TypeName PSCredential -ArgumentList $applicationId, $key
Clear-AzureRmContextConnect-AzureRMAccount -ServicePrincipal -Credential $cred -Tenant "TENANT1_ID"

Get-AzureRmResourceGroup
$vnet1 = Get-AzureRmVirtualNetwork -ResourceGroupName "vnetpeer1" -Name "vnetpeer1"
Add-AzureRmVirtualNetworkPeering `
-Name 'peer1-peer2' `
-VirtualNetwork $vnet1 `
-RemoteVirtualNetworkId "/subscriptions/SUBSCRIPTION2_ID/resourceGroups/vnetpeer2/providers/Microsoft.Network/virtualNetworks/vnetpeer2" ` -Debug
Connect-AzureRMAccount -ServicePrincipal -Credential $cred -Tenant "TENANT2_ID"
Get-AzureRmResourceGroup
$vnet2 = Get-AzureRmVirtualNetwork -ResourceGroupName "vnetpeer2" -Name "vnetpeer2"
Add-AzureRmVirtualNetworkPeering ` -Name 'peer2-peer1' ` -VirtualNetwork $vnet2 ` -RemoteVirtualNetworkId "/subscriptions/SUBSCRIPTION1_ID/resourceGroups/vnetpeer1/providers/Microsoft.Network/virtualNetworks/vnetpeer1"

Azure CLI Example

## Azure CLI login using service principal authentication
az account clear
az login --service-principal -u "CLIENT_ID" -p "CLIENT_SECRET" --tenant "TENANT1_ID"
az account get-access-token

az login --service-principal -u "CLIENT_ID" -p "CLIENT_SECRET" --tenant "TENANT2_ID"
az account get-access-token
## The following did not work properly in Azure CLI version 2.0.50 when using multi-tenanted application service principal
## However, as of 2018-11-27, the issue is fixed in Azure CLI versions 2.0.52 and later via this pull request https://github.com/Azure/azure-cli/pull/7916
az network vnet peering create --name vnet1-vnet2 --resource-group vnetpeer1 --vnet-name vnetpeer1 --remote-vnet "/subscriptions/SUBSCRIPTION2_ID/resourceGroups/vnetpeer2/providers/Microsoft.Network/virtualNetworks/vnetpeer2" --allow-vnet-access
az network vnet peering create --name vnet2-vnet1 --resource-group vnetpeer2 --vnet-name vnetpeer2 --remote-vnet "/subscriptions/SUBSCRIPTION1_ID/resourceGroups/vnetpeer1/providers/Microsoft.Network/virtualNetworks/vnetpeer1" --allow-vnet-access

ARM REST API Example

# Create VNet Peering in Subscription 1
curl -X PUT \
'https://management.azure.com/subscriptions/SUBSCRIPTION1_ID/resourceGroups/vnetpeer1/providers/Microsoft.Network/virtualNetworks/vnetpeer1/virtualNetworkPeerings/peer1-peer2?api-version=2018-02-01' \
-H 'Authorization: Bearer TENANT1_TOKEN' \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-H 'x-ms-authorization-auxiliary: Bearer TENANT2_TOKEN' \
-d '{ "properties": { "allowVirtualNetworkAccess": true, "allowForwardedTraffic": false, "allowGatewayTransit": false, "useRemoteGateways": false, "remoteVirtualNetwork": { "id": "/subscriptions/SUBSCRIPTION2_ID/resourceGroups/vnetpeer2/providers/Microsoft.Network/virtualNetworks/vnetpeer2" } } }'
# Create VNet Peering in Subscription 2curl -X PUT \
'https://management.azure.com/subscriptions/SUBSCRIPTION2_ID/resourceGroups/vnetpeer2/providers/Microsoft.Network/virtualNetworks/vnetpeer2/virtualNetworkPeerings/peer2-peer1?api-version=2018-02-01' \
-H 'Authorization: Bearer TENANT2_TOKEN' \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-H 'x-ms-authorization-auxiliary: Bearer TENANT1_TOKEN' \
-d '{ "properties": { "allowVirtualNetworkAccess": true, "allowForwardedTraffic": false, "allowGatewayTransit": false, "useRemoteGateways": false, "remoteVirtualNetwork": { "id": "/subscriptions/SUBSCRIPTION1_ID/resourceGroups/vnetpeer1/providers/Microsoft.Network/virtualNetworks/vnetpeer1" } } }'

--

--

Principal Engineer / Architect, FastTrack for Azure at Microsoft

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Arsen Vladimirskiy

Arsen Vladimirskiy

Principal Engineer / Architect, FastTrack for Azure at Microsoft