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


In this this video, we look at how to create Azure Virtual Network Peering across subscriptions that are in different Azure Active Directory tenants using Service Principal authentication. We look at how to mark Azure AD application in one of the tenants as "multi-tenanted", how to consent to the multi-tenanted application from the second tenant, and how to establish the VNet peering using Service Principal authentication using Azure PowerShell and Azure Resource Manager REST API calls via Postman.

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

Update November 27, 2018: At 14:21 in the video above I mentioned that Azure CLI version 2.0.50 does not work properly with multi-tenanted service principals across tenant. As of November 27, Azure CLI team fixed the bug via Pull Request #7916 and future Azure CLI versions 2.0.52 and later will work properly. I tested just now using Docker image latest dev azure-cli build “docker run --it azuresdk/azure-cli-python:dev.

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.

Consent URL example

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-AzureRmContext

Connect-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 2

curl -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" } } }'

Thank you!

Please leave feedback and questions below or on Twitter https://twitter.com/ArsenVlad

Comments (0)

Skip to main content