Introduction
In today’s cloud-first landscape, resilient network architectures not only enhance security but also facilitate seamless connectivity between distributed resources. In this installment, we explore two essential capabilities:
- VNet Peering: Enabling seamless, low-latency connectivity between Virtual Networks within the same region and across different regions.
- Subnet Peering: Taking VNet peering to a lower level deeper, allowing specific subnets within Virtual Networks to be peered to over Virtual Network subnets, increasing security by not having broad networks connected but specific subnets instead.
We will demonstrate how to implement this solution using both the Azure Portal and Bicep templates. Whether you prefer the intuitive UI or automated, repeatable deployments via Infrastructure-as-Code, you’ll find practical steps and code samples to guide your setup.
VNet Peering: Connecting Virtual Networks
Concept Overview
VNet peering allows you to connect two virtual networks in Azure so that resources in different VNets can communicate with each other via the Microsoft backbone network. Peering can be done:
- Within the same region: For low latency, high-bandwidth connectivity.
- Across regions: Enabling global networking scenarios, though take note that data transfer costs may apply.
This connectivity model is ideal for building resilient architectures that span multiple deployments, environments, or even geographic locations.
ℹ️
Importance of Planning with IPAM
Extending your on-premises infrastructure to the cloud requires plenty of advanced planning, no more so than in networking. When you being the planning stages of your cloud adoption you need to allocate a IP address range that does not overlap with your internal ranges to avoid the costly re-work required to fix the problem in future.
Subnet Peering: Connecting Subnets across Virtual Networks
Concept Overview
Subnet peering enables more granular connectivity by allowing you to peer selected subnets between virtual networks instead of merging the entire address space, as is the case with standard VNet peering. This extra level of control is particularly beneficial in scenarios such as micro-segmentation, where you may want only specific tiers or service components to communicate across virtual networks while keeping other parts isolated for security or network management purposes.
With subnet peering, you can:
- Selectively Share IP Space: Rather than exposing all subnets within a virtual network, you can specify which subnets should be privy to traffic from a remote network. This reduces the attack surface and maintains clearer security boundaries.
- Optimise IP Space Allocation: For organisations facing IP address exhaustion, subnet peering allows the sharing of only parts of the IP space that are needed for inter-VNet communication, rather than requiring a large, contiguous block of addresses.
- Enhance Security and Compliance: By limiting connectivity to only designated subnets, you can implement internal segmentation strategies that better align with your organisational security policies and regulatory requirements.
ℹ️
Subnet peering is currently in public preview. This means it’s available through the Azure CLI, PowerShell, API, and ARM templates—but not yet via the Azure Portal.
To enable subnet peering, you must set parameters such as --peer-complete-vnets
to false
and specify the local and remote subnet names you wish to peer.
Before using subnet level peering you need to ensure that Microsoft.Network/AllowMultiplePeeringLinksBetweenVnets preview feature is enabled in your subscription
1
2
|
Set-AzContext -Subscription "Subscription Name"
Register-AzProviderFeature -FeatureName AllowMultiplePeeringLinksBetweenVnets -ProviderNamespace Microsoft.Network
|
A Architecture Diagram
I have always find it best to understand these concepts using diagrams
Here is an example of Geo Peering where the peering happens across regions
architecture-beta
group azure(cloud)[Azure]
group clouda(cloud)[Australia Southeast] in azure
service vnet01(fluent:virtual-network-20-filled)[MyVnet01] in clouda
service vm01(fluent:server-20-filled)[Virtual Machine] in clouda
group cloudb(cloud)[Australia East] in azure
service vnet02(fluent:virtual-network-20-filled)[MyVnet02] in cloudb
service vm02(fluent:server-20-filled)[Virtual Machine] in cloudb
vm01:T -- B:vnet01
vnet02:B -- T:vm02
vnet01:R <--> L:vnet02
Here is an example of local vnet peering
architecture-beta
group clouda(cloud)[Azure Australia East]
service vnet01(fluent:virtual-network-20-regular)[MyVnet01] in clouda
service vm01(fluent:server-20-filled)[Virtual Machine] in clouda
service vnet02(fluent:virtual-network-20-regular)[MyVnet02] in clouda
service vm02(fluent:server-20-filled)[Virtual Machine] in clouda
vm01:T -- B:vnet01
vnet02:B -- T:vm02
vnet01:R <--> L:vnet02
Here is an example where using Gateway Traversal allows connectivity back to on-prem
architecture-beta
group clouda(cloud)[Azure Australia East]
group rghub(cloud)[Hub Resource Group] in clouda
group rgvm(cloud)[Workload Resource Group] in clouda
service vnet01(fluent:virtual-network-20-regular)[MyVnet01] in rghub
service vnet03(fluent:virtual-network-20-regular)[MyVnet02] in rgvm
service vm01(fluent:server-20-filled)[Virtual Machine] in rgvm
service gateway(mdi:vpn)[VPN Gateway] in rghub
group onprem(cloud)[On Prem]
service vnet02(fluent:virtual-network-20-regular)[Network] in onprem
service vm02(fluent:server-20-filled)[Virtual Machine] in onprem
service firewall(mdi:firewall)[OnPrem Firewall] in onprem
vm01:L -- R:vnet03
vnet01:B <--> T:vnet03
vnet02:B -- T:vm02
vnet01:R -- L:gateway
gateway:R <--> L:firewall
firewall:R -- L:vnet02
And finally here is a conceptual diagram of subnet peering where we will create bidrectional routing between MySubnetB in MyVnet01 and MySubnetD and MySubnetF in MyVnet02. This will allow for VM 02 to be able to communicate with VM 04 & 06 without allowing other VM’s to communicate between these Virtual Networks.
architecture-beta
group azure(cloud)[Azure]
group clouda(cloud)[Australia East] in azure
group vnet01(fluent:virtual-network-20-filled)[MyVnet01] in clouda
service subneta(fluent:virtual-network-20-filled)[MySubnetA] in vnet01
service subnetb(fluent:virtual-network-20-filled)[MySubnetB] in vnet01
service subnetc(fluent:virtual-network-20-filled)[MySubnetC] in vnet01
service vm01(fluent:server-20-filled)[VM 01] in vnet01
service vm02(fluent:server-20-filled)[VM 02] in vnet01
service vm03(fluent:server-20-filled)[VM 03] in vnet01
vm01:L <--> R:subneta
vm02:L <--> R:subnetb
vm03:L <--> R:subnetc
group vnet02(fluent:virtual-network-20-filled)[MyVnet02] in clouda
service subnetd(fluent:virtual-network-20-filled)[MySubnetD] in vnet02
service subnete(fluent:virtual-network-20-filled)[MySubnetE] in vnet02
service subnetf(fluent:virtual-network-20-filled)[MySubnetF] in vnet02
service vm04(fluent:server-20-filled)[VM 04] in vnet02
service vm05(fluent:server-20-filled)[VM 05] in vnet02
service vm06(fluent:server-20-filled)[VM 06] in vnet02
vm04:R <--> L:subnetd
vm05:R <--> L:subnete
vm06:R <--> L:subnetf
subnetb:L <--> R:subnetd
subnetb:L <--> R:subnetf
Implementing VNet Peering via the Azure Portal
-
Sign In and Navigate to Virtual Networks:
- Open the Azure Portal and go to your Virtual Networks.
- Select the first VNet (e.g., MyVNet1).
-
Add a Peering Connection:
- In the Settings section, click on Peerings and then + Add.
- Name the peering (e.g., MyVNet1-to-MyVNet2).
- Under Peering link, select the remote Virtual Network (e.g., MyVNet2) and confirm the configuration options:
- Allow virtual network access: Enabled.
- Allow forwarded traffic: As per your requirement.
- Use remote gateways / Allow gateway transit: Configure if a VPN gateway on the remote side needs to be shared.
- Click OK to create the peering.
-
Repeat for Reverse Peering:
- Ensure that the remote VNet (MyVNet2) also has a peering configuration pointing back to MyVNet1.
Implementing VNet Peering via Bicep
Use the following Bicep snippet to deploy a VNet peering between two existing VNets. Adjust the resource names and IDs as needed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
// Parameters for flexible deployment
param vnet1Name string = 'MyVNet-01'
param location string = resourceGroup().location
param address1Prefix string = '10.0.0.0/16'
param subnet1Name string = 'MySubnet-01'
param subnet1Prefix string = '10.0.1.0/24'
param vnet2Name string = 'MyVNet-02'
param address2Prefix string = '10.1.0.0/16'
param subnet2Name string = 'MySubnet-02'
param subnet2Prefix string = '10.1.1.0/24'
resource vnet1 'Microsoft.Network/virtualNetworks@2024-05-01' = {
name: vnet1Name
location: location
properties: {
addressSpace: {
addressPrefixes: [
address1Prefix
]
}
subnets: [
{
name: subnet1Name
properties: {
addressPrefix: subnet1Prefix
}
}
]
}
}
resource vnet2 'Microsoft.Network/virtualNetworks@2024-05-01' = {
name: vnet2Name
location: location
properties: {
addressSpace: {
addressPrefixes: [
address2Prefix
]
}
subnets: [
{
name: subnet2Name
properties: {
addressPrefix: subnet2Prefix
}
}
]
}
}
resource vnetPeering1 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2024-05-01' = {
name: '${vnet1.name}-To-${vnet2.name}'
parent: vnet1
properties: {
remoteVirtualNetwork: {
id: vnet2.id
}
allowVirtualNetworkAccess: true
allowForwardedTraffic: false
allowGatewayTransit: false
useRemoteGateways: false
}
}
resource vnetPeering2 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2024-05-01' = {
name: '${vnet2.name}-To-${vnet2.name}'
parent: vnet2
properties: {
remoteVirtualNetwork: {
id: vnet1.id
}
allowVirtualNetworkAccess: true
allowForwardedTraffic: false
allowGatewayTransit: false
useRemoteGateways: false
}
}
|
Deployment Steps:
-
Save the template as VirtualNetworkPeeringDeployment.bicep
.
-
Open your terminal and run:
1
2
3
4
|
az login
az deployment group create \
--resource-group MyResourceGroup \
--template-file VirtualNetworkPeeringDeployment.bicep
|
Implementing Subnet Peering via Bicep
ℹ️
At the time of writting this article there is currently no ability to complete subnet peering within the Azure Portal
Use the following Bicep snippet to deploy a Subnet peering between two existing VNets. Adjust the resource names and IDs as needed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
// This Bicep template creates two virtual networks with multiple subnets and sets up peering between them.
@description('Location of the Resources to be created')
param location string = resourceGroup().location
@description('Name of the first Virtual Network')
param vnet1Name string = 'MyVnet01'
@description('Address prefix for the first Virtual Network')
param vnet1AddressPrefix string = '10.0.0.0/16'
@description('Subnets for the first Virtual Network')
var vnet1Subnets = [
{ name: 'subneta', addressPrefix: '10.0.1.0/24' }
{ name: 'subnetb', addressPrefix: '10.0.2.0/24' }
{ name: 'subnetc', addressPrefix: '10.0.3.0/24' }
]
@description('Name of the second Virtual Network')
param vnet2Name string = 'MyVnet02'
@description('Address prefix for the second Virtual Network')
param vnet2AddressPrefix string = '10.1.0.0/16'
@description('Subnets for the second Virtual Network')
var vnet2Subnets = [
{ name: 'subnetd', addressPrefix: '10.1.1.0/24' }
{ name: 'subnete', addressPrefix: '10.1.2.0/24' }
{ name: 'subnetf', addressPrefix: '10.1.3.0/24' }
]
// Create the first Virtual Network with subnets
resource vnet1 'Microsoft.Network/virtualNetworks@2024-05-01' = {
name: vnet1Name
location: location
properties: {
addressSpace: {
addressPrefixes: [vnet1AddressPrefix]
}
subnets: [for subnet in vnet1Subnets: {
name: subnet.name
properties: {
addressPrefix: subnet.addressPrefix
}
}]
}
}
// Create the second Virtual Network with subnets
resource vnet2 'Microsoft.Network/virtualNetworks@2024-05-01' = {
name: vnet2Name
location: location
properties: {
addressSpace: {
addressPrefixes: [vnet2AddressPrefix]
}
subnets: [for subnet in vnet2Subnets: {
name: subnet.name
properties: {
addressPrefix: subnet.addressPrefix
}
}]
}
}
// This peering allows access from SubnetA and SubnetC of VNet1 to SubnetD and SubnetF of VNet2
resource peering1 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2024-05-01' = {
name: '${vnet1Name}-to-${vnet2Name}-SubnetB-to-SubnetD-and-SubnetF'
parent: vnet1
properties: {
remoteVirtualNetwork: {
id: vnet2.id
}
peerCompleteVnets: false
localSubnetNames: [
'subnetb'
]
remoteSubnetNames: [
'subnetd'
'subnetf'
]
allowVirtualNetworkAccess: true
allowForwardedTraffic: false
allowGatewayTransit: false
useRemoteGateways: false
}
}
// This peering allows access from SubnetD and SubnetF of VNet2 to SubnetB of VNet1
resource peering2 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2024-05-01' = {
name: '${vnet2Name}-to-${vnet1Name}-SubnetF-and-SubnetD-to-SubnetB'
parent: vnet2
properties: {
remoteVirtualNetwork: {
id: vnet1.id
}
peerCompleteVnets: false
localSubnetNames: [
'subnetf'
'subnetd'
]
remoteSubnetNames: [
'subnetb'
]
allowVirtualNetworkAccess: true
allowForwardedTraffic: false
allowGatewayTransit: false
useRemoteGateways: false
}
}
|
Deployment Steps:
-
Save the template as SubnetPeeringDeployment.bicep
.
-
Open your terminal and run:
1
2
3
4
|
az login
az deployment group create \
--resource-group MyResourceGroup \
--template-file SubnetPeeringDeployment.bicep
|
Conclusion
Building resilient networks in Azure means ensuring that connectivity isn’t just robust but also flexible enough to span both cloud and on-premises resources. VNet Peering provides the ability to interconnect VNets within and across regions to enable seamless communication.
Implementing robust networking strategies using both the Azure Portal and Bicep provides you with the versatility to manage and automate your deployments according to your organisational needs.
Learn More