Azure Landing Zones Part 2 - Connectivity the Backbone of Your Azure Landing Zone

Azure Landing Zones Part 2 - Connectivity the Backbone of Your Azure Landing Zone

Welcome back to our Azure Landing Zones series! In the last post, we introduced Azure Landing Zones as the ultimate framework for building a scalable, secure, and well-organized Azure infrastructure. Now, we’re ready to roll up our sleeves and get hands-on with the first piece of the puzzle: the Connectivity Subscription.

Think of the Connectivity Subscription as the backbone of your Azure network. It’s your cloud superhighway, connecting workloads, securing hybrid connectivity, and keeping everything running smoothly. By the end of this post, you’ll have deployed a powerful Connectivity Subscription using a feature-packed Bicep template, designed for scalability and resilience. Let’s get started!


What Is a Connectivity Subscription?

The Connectivity Subscription is a dedicated Azure subscription that hosts critical networking resources. It establishes a secure and scalable network foundation for your Azure environment.

Key Features:

  • Hub Virtual Network (VNet): The central hub of your network topology.
  • Azure Firewall: A cloud-native solution to secure and control traffic.
  • VPN Gateway: Secure hybrid connectivity between Azure and on-premises resources.
  • Azure Bastion: Safe and private remote access to your virtual machines.

What Are We Building Today?

In this post, we’ll deploy the following resources as part of the Connectivity Subscription:

  1. Hub VNet with subnets for:
    • Azure Firewall
    • VPN Gateway
    • Azure Bastion
  2. Azure Firewall to secure and monitor network traffic.
  3. VPN Gateway with active-active redundancy for hybrid connectivity.
  4. Azure Bastion for secure, password-less VM access.
  5. Zone-redundant Public IPs for enhanced resilience.

Why Use VpnGw1AZ and Zone-Redundant Public IPs?

1. VpnGw1AZ SKU for the VPN Gateway

The VpnGw1AZ SKU is a zone-aware gateway designed for high availability. This SKU enables active-active configuration, which offers:

  • Increased Resilience: Active-active VPN Gateway ensures that if one instance fails, the other continues to handle traffic without downtime.
  • Improved Performance: Load-balancing traffic across multiple gateway instances enhances overall throughput and reduces latency.
  • Zone Awareness: This SKU deploys instances across multiple availability zones, ensuring that your hybrid connectivity remains operational even if one zone experiences a failure. Note that active-active isn't required

Important Update on VPN Gateway SKUs

Microsoft has announced changes to the availability of VPN Gateway SKUs:

  • Effective January 1, 2025: Creation of new VPN gateways using non-AZ SKUs (VpnGw1-5) will no longer be possible. This ensures that all new deployments leverage zone-aware infrastructure, increasing reliability and resilience.
  • Migration Period: From April 2025 to September 2026, existing VPN gateways using non-AZ SKUs (VpnGw1-5) will be seamlessly migrated to the equivalent zone-aware SKUs (VpnGw1AZ-5AZ). This migration will be managed by Microsoft, ensuring minimal disruption to your workloads.

For more information, see the official Azure documentation on gateway SKU consolidation.

2. Zone-Redundant Public IPs

Zone-redundant Public IPs are critical for achieving high availability in your network design. These IPs:

  • Provide Fault Tolerance: Public IP addresses are distributed across multiple availability zones, ensuring that they remain reachable even during zone outages.
  • Complement Zone-Aware Resources: Azure Firewall, VPN Gateway, and other services benefit from zone-redundant public IPs to maintain seamless connectivity.
  • Future-Proof Your Environment: Zone redundancy ensures your infrastructure is aligned with modern resilience standards, reducing risks during regional disruptions.

By combining VpnGw1AZ SKU and zone-redundant Public IPs, we’re designing a network that is not only resilient and scalable but also compliant with Azure’s forward-looking policies.


Step 1: Understanding the Bicep Template

The provided Bicep template defines all the resources you’ll need for your Connectivity Subscription, including subnets, public IPs, and network components. Here’s the template:

Note that the names in the bicep DOSN'T follow any naming conventions and is used to make everything easier to read.

targetScope = 'resourceGroup'

param location string = 'Sweden Central'
//Vnet
param vnetName string = 'HubVNet'
param vnetAddressSpace string = '10.0.0.0/16'

// Public IPs
param firewallPublicIp string = 'HubFirewallIP'
param activeVpnGatewayPublicIp string = 'ActiveVpnGatewayIP'
param vpnGatewayPublicIp string = 'VpnGatewayIP'
param bastionPublicIp string = 'BastionIP'

// FireWall
param firewallName string = 'HubFirewall'

// VPN Gateway
param vpnGatewayName string = 'HubVpnGateway'

// Bastion
param bastionName string = 'HubBastion'



resource hubVNet 'Microsoft.Network/virtualNetworks@2023-02-01' = {
  name: vnetName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [vnetAddressSpace]
    }
    subnets: [
      {
        name: 'AzureFirewallSubnet'
        properties: {
          addressPrefix: '10.0.1.0/24'
        }
      }
      {
        name: 'GatewaySubnet'
        properties: {
          addressPrefix: '10.0.2.0/24'
        }
      }
      {
        name: 'AzureBastionSubnet'
        properties: {
          addressPrefix: '10.0.3.0/24'
        }
      }
    ]
  }
}

resource publicIPFirewall 'Microsoft.Network/publicIPAddresses@2023-02-01' = {
  name: firewallPublicIp
  location: location
  sku: {
    name: 'Standard'
  }
  properties: {
    publicIPAllocationMethod: 'Static'
  }
}

resource activeGatewayNewPublicIpAddress 'Microsoft.Network/publicIPAddresses@2020-08-01' = {
  name: activeVpnGatewayPublicIp
  location: location
  sku: {
    name: 'Standard'
  }
  properties: {
    publicIPAllocationMethod: 'Static'
  }
  zones: [
    '1'
    '2'
    '3'
  ]
}

resource vpnPublicIpAddress 'Microsoft.Network/publicIPAddresses@2020-08-01' = {
  name: vpnGatewayPublicIp
  location: location
  sku: {
    name: 'Standard'
  }
  properties: {
    publicIPAllocationMethod: 'Static'
  }
  zones: [
    '1'
    '2'
    '3'
  ]
}

resource publicIPBastion 'Microsoft.Network/publicIPAddresses@2023-02-01' = {
  name: bastionPublicIp
  location: location
  sku: {
    name: 'Standard'
  }
  properties: {
    publicIPAllocationMethod: 'Static'
  }
}

resource azureFirewall 'Microsoft.Network/azureFirewalls@2023-02-01' = {
  name: firewallName
  location: location
  properties: {
    sku: {
      name: 'AZFW_VNet'
      tier: 'Standard'
    }
    ipConfigurations: [
      {
        name: 'ipConfig'
        properties: {
          subnet: {
            id: hubVNet.properties.subnets[0].id
          }
          publicIPAddress: {
            id: publicIPFirewall.id
          }
        }
      }
    ]
  }
}

resource vpnGateway 'Microsoft.Network/virtualNetworkGateways@2024-01-01' = {
  name: vpnGatewayName
  location: location
  properties: {
    gatewayType: 'Vpn'
    ipConfigurations: [
      {
        name: 'default'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          subnet: {
            id: hubVNet.properties.subnets[1].id
          }
          publicIPAddress: {
            id: resourceId('Microsoft.Network/publicIPAddresses', 'VpnGatewayIP')
          }
        }
      }
      {
        name: 'activeActive'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: resourceId('Microsoft.Network/publicIPAddresses', 'ActiveVpnGatewayIP')
          }
          subnet: {
            id: hubVNet.properties.subnets[1].id 
          }
        }
      }
    ]
    activeActive: true
    vpnType: 'RouteBased'
    vpnGatewayGeneration: 'Generation1'
    sku: {
      name: 'VpnGw1AZ'
      tier: 'VpnGw1AZ'
    }
  }
  dependsOn: [
    activeGatewayNewPublicIpAddress
    vpnPublicIpAddress
  ]
}

resource bastion 'Microsoft.Network/bastionHosts@2023-02-01' = {
  name: bastionName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'bastionConfig'
        properties: {
          subnet: {
            id: hubVNet.properties.subnets[2].id 
          }
          publicIPAddress: {
            id: publicIPBastion.id
          }
        }
      }
    ]
  }
}


Step 2: Deploying the Template

  1. Set up a Resource Group:

    az group create --name ConnectivityRG --location "Sweden Central"
    
  2. Deploy the Template:

    az deployment group create --resource-group ConnectivityRG --template-file ./connectivity-subscription.bicep