Quickstart: Create an ExpressRoute circuit with private peering using Bicep
This quickstart describes how to use Bicep to create an ExpressRoute circuit with private peering.
Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources. It provides concise syntax, reliable type safety, and support for code reuse. Bicep offers the best authoring experience for your infrastructure-as-code solutions in Azure.
Prerequisites
If you don't have an Azure subscription, create a free account before you begin.
Review the Bicep file
The Bicep file used in this quickstart is from Azure Quickstart Templates.
In this quickstart, you create an ExpressRoute circuit with Equinix as the service provider. The circuit is using a Premium SKU, with a bandwidth of 50 Mbps, and the peering location of Washington DC. Private peering is enabled with a primary and secondary subnet of 192.168.10.16/30 and 192.168.10.20/30 respectively. A virtual network gets created along with a HighPerformance ExpressRoute gateway.
@description('Location for all resources deployed in the Bicep file')
param location string = resourceGroup().location
@description('ExpressRoute peering location')
param erpeeringLocation string = 'Washington DC'
@description('Name of the ExpressRoute circuit')
param erCircuitName string = 'er-ckt01'
@description('Name of the ExpressRoute provider')
param serviceProviderName string = 'Equinix'
@description('Tier ExpressRoute circuit')
@allowed([
'Premium'
'Standard'
])
param erSKU_Tier string = 'Premium'
@description('Billing model ExpressRoute circuit')
@allowed([
'MeteredData'
'UnlimitedData'
])
param erSKU_Family string = 'MeteredData'
@description('Bandwidth ExpressRoute circuit')
@allowed([
50
100
200
500
1000
2000
5000
10000
])
param bandwidthInMbps int = 50
@description('autonomous system number used to create private peering between the customer edge router and MSEE routers')
param peerASN int = 65001
@description('point-to-point network prefix of primary link between the customer edge router and MSEE router')
param primaryPeerAddressPrefix string = '192.168.10.16/30'
@description('point-to-point network prefix of secondary link between the customer edge router and MSEE router')
param secondaryPeerAddressPrefix string = '192.168.10.20/30'
@description('VLAN Id used between the customer edge routers and MSEE routers. primary and secondary link have the same VLAN Id')
param vlanId int = 100
@description('name of the Virtual Network')
param vnetName string = 'vnet1'
@description('name of the subnet')
param subnet1Name string = 'subnet1'
@description('address space assigned to the Virtual Network')
param vnetAddressSpace string = '10.10.10.0/24'
@description('network prefix assigned to the subnet')
param subnet1Prefix string = '10.10.10.0/25'
@description('network prefixes assigned to the gateway subnet. It has to be a network prefix with mask /27 or larger')
param gatewaySubnetPrefix string = '10.10.10.224/27'
@description('name of the ExpressRoute Gateway')
param gatewayName string = 'er-gw'
@description('ExpressRoute Gateway SKU')
@allowed([
'Standard'
'HighPerformance'
'UltraPerformance'
'ErGw1AZ'
'ErGw2AZ'
'ErGw3AZ'
])
param gatewaySku string = 'HighPerformance'
var erSKU_Name = '${erSKU_Tier}_${erSKU_Family}'
var gatewayPublicIPName = '${gatewayName}-pubIP'
var nsgName = 'nsg'
resource erCircuit 'Microsoft.Network/expressRouteCircuits@2023-09-01' = {
name: erCircuitName
location: location
sku: {
name: erSKU_Name
tier: erSKU_Tier
family: erSKU_Family
}
properties: {
serviceProviderProperties: {
serviceProviderName: serviceProviderName
peeringLocation: erpeeringLocation
bandwidthInMbps: bandwidthInMbps
}
allowClassicOperations: false
}
}
resource peering 'Microsoft.Network/expressRouteCircuits/peerings@2023-09-01' = {
parent: erCircuit
name: 'AzurePrivatePeering'
properties: {
peeringType: 'AzurePrivatePeering'
peerASN: peerASN
primaryPeerAddressPrefix: primaryPeerAddressPrefix
secondaryPeerAddressPrefix: secondaryPeerAddressPrefix
vlanId: vlanId
}
}
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-09-01' = {
name: nsgName
location: location
properties: {
securityRules: [
{
name: 'SSH-rule'
properties: {
description: 'allow SSH'
protocol: 'Tcp'
sourcePortRange: '*'
destinationPortRange: '22'
sourceAddressPrefix: '*'
destinationAddressPrefix: 'VirtualNetwork'
access: 'Allow'
priority: 500
direction: 'Inbound'
}
}
{
name: 'RDP-rule'
properties: {
description: 'allow RDP'
protocol: 'Tcp'
sourcePortRange: '*'
destinationPortRange: '3389'
sourceAddressPrefix: '*'
destinationAddressPrefix: 'VirtualNetwork'
access: 'Allow'
priority: 600
direction: 'Inbound'
}
}
]
}
}
resource vnet 'Microsoft.Network/virtualNetworks@2023-09-01' = {
name: vnetName
location: location
properties: {
addressSpace: {
addressPrefixes: [
vnetAddressSpace
]
}
subnets: [
{
name: subnet1Name
properties: {
addressPrefix: subnet1Prefix
networkSecurityGroup: {
id: nsg.id
}
}
}
{
name: 'GatewaySubnet'
properties: {
addressPrefix: gatewaySubnetPrefix
}
}
]
}
}
resource gatewayPublicIP 'Microsoft.Network/publicIPAddresses@2023-09-01' = {
name: gatewayPublicIPName
location: location
sku: {
name: 'Standard'
tier: 'Regional'
}
properties: {
publicIPAllocationMethod: 'Static'
}
}
resource gateway 'Microsoft.Network/virtualNetworkGateways@2023-09-01' = {
name: gatewayName
location: location
properties: {
ipConfigurations: [
{
properties: {
privateIPAllocationMethod: 'Dynamic'
subnet: {
id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, 'GatewaySubnet')
}
publicIPAddress: {
id: gatewayPublicIP.id
}
}
name: 'gwIPconf'
}
]
gatewayType: 'ExpressRoute'
sku: {
name: gatewaySku
tier: gatewaySku
}
vpnType: 'RouteBased'
}
dependsOn: [
vnet
]
}
output erCircuitName string = erCircuitName
output gatewayName string = gatewayName
output gatewaySku string = gatewaySku
Multiple Azure resources have been defined in the Bicep file:
- Microsoft.Network/expressRouteCircuits
- Microsoft.Network/expressRouteCircuits/peerings (Used to enabled private peering on the circuit)
- Microsoft.Network/networkSecurityGroups (network security group is applied to the subnets in the virtual network)
- Microsoft.Network/virtualNetworks
- Microsoft.Network/publicIPAddresses (Public IP is used by the ExpressRoute gateway)
- Microsoft.Network/virtualNetworkGateways (ExpressRoute gateway is used to link VNet to the circuit)
Deploy the Bicep file
Save the Bicep file as main.bicep to your local computer.
Deploy the Bicep file using either Azure CLI or Azure PowerShell.
az group create --name exampleRG --location eastus az deployment group create --resource-group exampleRG --template-file main.bicep
When the deployment finishes, you should see a message indicating the deployment succeeded.
Validate the deployment
Use the Azure portal, Azure CLI, or Azure PowerShell to list the deployed resources in the resource group.
az resource list --resource-group exampleRG
Note
You will need to call the provider to complete the provisioning process before you can link the virtual network to the circuit.
Clean up resources
When no longer needed, use the Azure portal, Azure CLI, or Azure PowerShell to delete the VM and all of the resources in the resource group.
az group delete --name exampleRG
Next steps
In this quickstart, you created a:
- ExpressRoute circuit
- Virtual Network
- VPN Gateway
- Public IP
- Network security group
To learn how to link a virtual network to a circuit, continue to the ExpressRoute tutorials.