Hybrid Connectivity
How to design ExpressRoute, VPN, and Azure Arc for hybrid environments.
Hybrid Architecture Overview
ExpressRoute
ExpressRoute Architecture
ExpressRoute SKUs
| SKU | Bandwidth | Use Case |
|---|---|---|
| Local | 1-10 Gbps | Same metro as peering location |
| Standard | 50 Mbps - 10 Gbps | Single geo (North America, Europe, etc.) |
| Premium | 50 Mbps - 100 Gbps | Global connectivity |
ExpressRoute Gateway SKUs
| SKU | Throughput | Circuits | Use Case |
|---|---|---|---|
| Standard | 1 Gbps | 4 | Small workloads |
| HighPerformance | 2 Gbps | 4 | Medium workloads |
| UltraPerformance | 10 Gbps | 16 | Large workloads |
| ErGw1AZ | 1 Gbps | 4 | Zone-redundant |
| ErGw2AZ | 2 Gbps | 8 | Zone-redundant |
| ErGw3AZ | 10 Gbps | 16 | Zone-redundant, recommended |
Bicep: ExpressRoute Configuration
// ExpressRoute Circuit
resource expressRouteCircuit 'Microsoft.Network/expressRouteCircuits@2023-05-01' = {
name: 'erc-contoso-eastus-001'
location: location
sku: {
name: 'Premium_MeteredData'
tier: 'Premium'
family: 'MeteredData'
}
properties: {
serviceProviderProperties: {
serviceProviderName: 'Equinix'
peeringLocation: 'Washington DC'
bandwidthInMbps: 1000
}
}
}
// ExpressRoute Gateway
resource expressRouteGateway 'Microsoft.Network/virtualNetworkGateways@2023-05-01' = {
name: 'ergw-hub-eastus-001'
location: location
properties: {
gatewayType: 'ExpressRoute'
sku: {
name: 'ErGw3AZ'
tier: 'ErGw3AZ'
}
ipConfigurations: [
{
name: 'default'
properties: {
privateIPAllocationMethod: 'Dynamic'
subnet: {
id: '${hubVnet.id}/subnets/GatewaySubnet'
}
publicIPAddress: {
id: gatewayPip.id
}
}
}
]
}
}
// Connection
resource expressRouteConnection 'Microsoft.Network/connections@2023-05-01' = {
name: 'con-er-eastus-001'
location: location
properties: {
connectionType: 'ExpressRoute'
virtualNetworkGateway1: {
id: expressRouteGateway.id
}
peer: {
id: expressRouteCircuit.id
}
authorizationKey: authorizationKey // From circuit owner
}
}
ExpressRoute Global Reach
VPN Gateway
VPN Architecture
VPN Gateway SKUs
| SKU | S2S Tunnels | P2S | Throughput |
|---|---|---|---|
| Basic | 10 | 128 | 100 Mbps |
| VpnGw1 | 30 | 250 | 650 Mbps |
| VpnGw2 | 30 | 500 | 1 Gbps |
| VpnGw3 | 30 | 1000 | 1.25 Gbps |
| VpnGw4 | 100 | 5000 | 5 Gbps |
| VpnGw5 | 100 | 10000 | 10 Gbps |
| VpnGw1AZ | 30 | 250 | 650 Mbps (Zone) |
| VpnGw2AZ | 30 | 500 | 1 Gbps (Zone) |
Bicep: VPN Gateway with BGP
// VPN Gateway (Active-Active)
resource vpnGateway 'Microsoft.Network/virtualNetworkGateways@2023-05-01' = {
name: 'vpngw-hub-eastus-001'
location: location
properties: {
gatewayType: 'Vpn'
vpnType: 'RouteBased'
vpnGatewayGeneration: 'Generation2'
sku: {
name: 'VpnGw2AZ'
tier: 'VpnGw2AZ'
}
activeActive: true
enableBgp: true
bgpSettings: {
asn: 65515
bgpPeeringAddresses: [
{
ipconfigurationId: '${vpnGateway.id}/ipConfigurations/primary'
customBgpIpAddresses: ['169.254.21.1']
}
{
ipconfigurationId: '${vpnGateway.id}/ipConfigurations/secondary'
customBgpIpAddresses: ['169.254.22.1']
}
]
}
ipConfigurations: [
{
name: 'primary'
properties: {
privateIPAllocationMethod: 'Dynamic'
subnet: {
id: '${hubVnet.id}/subnets/GatewaySubnet'
}
publicIPAddress: {
id: vpnPip1.id
}
}
}
{
name: 'secondary'
properties: {
privateIPAllocationMethod: 'Dynamic'
subnet: {
id: '${hubVnet.id}/subnets/GatewaySubnet'
}
publicIPAddress: {
id: vpnPip2.id
}
}
}
]
}
}
// Local Network Gateway (On-Prem)
resource localNetworkGateway 'Microsoft.Network/localNetworkGateways@2023-05-01' = {
name: 'lng-onprem-001'
location: location
properties: {
gatewayIpAddress: '<on-prem-public-ip>'
bgpSettings: {
asn: 65000
bgpPeeringAddress: '<on-prem-bgp-ip>'
}
}
}
// S2S Connection
resource vpnConnection 'Microsoft.Network/connections@2023-05-01' = {
name: 'con-vpn-onprem-001'
location: location
properties: {
connectionType: 'IPsec'
virtualNetworkGateway1: {
id: vpnGateway.id
}
localNetworkGateway2: {
id: localNetworkGateway.id
}
sharedKey: sharedKey
enableBgp: true
ipsecPolicies: [
{
saLifeTimeSeconds: 3600
saDataSizeKilobytes: 102400000
ipsecEncryption: 'AES256'
ipsecIntegrity: 'SHA256'
ikeEncryption: 'AES256'
ikeIntegrity: 'SHA256'
dhGroup: 'DHGroup14'
pfsGroup: 'PFS2048'
}
]
}
}
Azure Arc
Arc Architecture
Arc-Enabled Servers
# Install Connected Machine agent (Windows)
$env:SUBSCRIPTION_ID = "<subscription-id>"
$env:RESOURCE_GROUP = "rg-arc-servers"
$env:TENANT_ID = "<tenant-id>"
$env:LOCATION = "eastus"
# Download and run the agent
Invoke-WebRequest -Uri https://aka.ms/azcmagent-windows -OutFile AzureConnectedMachineAgent.msi
msiexec /i AzureConnectedMachineAgent.msi /l*v installlog.txt /qn
# Connect to Azure
& "$env:ProgramFiles\AzureConnectedMachineAgent\azcmagent.exe" connect `
--resource-group $env:RESOURCE_GROUP `
--tenant-id $env:TENANT_ID `
--location $env:LOCATION `
--subscription-id $env:SUBSCRIPTION_ID
Arc Policy Assignment
resource arcPolicyAssignment 'Microsoft.Authorization/policyAssignments@2022-06-01' = {
name: 'deploy-arc-extensions'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
policyDefinitionId: '/providers/Microsoft.Authorization/policyDefinitions/845857af-0333-4c5d-bbbc-6076697da122' // Deploy Azure Monitor Agent
displayName: 'Deploy Azure Monitor Agent on Arc servers'
enforcementMode: 'Default'
parameters: {
effect: {
value: 'DeployIfNotExists'
}
}
}
}
ER + VPN Backup
Coexistence Architecture
BGP Route Configuration
On-Premises Router:
- ExpressRoute: Advertise with AS Path = 65000
- VPN: Advertise with AS Path = 65000 65000 65000 (prepend)
Azure will prefer ExpressRoute (shorter AS path)
Automatic failover to VPN when ER is down
Quick Reference Card
| Component | Recommendation |
|---|---|
| ExpressRoute | Premium for global, ErGw3AZ for HA |
| VPN | VpnGw2AZ minimum, Active-Active |
| BGP | Enable for automatic failover |
| Azure Arc | All hybrid servers |
| ER + VPN | VPN as backup for ER |
Next Steps
Continue to Sovereign Clouds to learn about government and regulated environments.