Skip to content

ExpressRoute Circuit

ExpressRoute Circuit

An ExpressRoute circuit represents a dedicated private connection between your on-premises network and Azure through a connectivity provider. Creating the circuit generates a service key that you give to your provider to complete the physical provisioning. The circuit does not carry traffic until the provider marks it as provisioned and peering is configured.

Billing note: Azure charges for the circuit from the moment it is created, regardless of provider provisioning state. Delete the resource promptly if deploying for testing purposes only.

Basic Configuration

Standard provider model (most common):

express_route_circuit = {
    er01 = {
        resource_group        = "hub"
        service_provider_name = "Equinix"
        peering_location      = "Seattle"
        bandwidth_in_mbps     = 1000

        sku = {
            tier   = "Standard"
            family = "MeteredData"
        }
    }
}

This creates a circuit in ServiceProviderProvisioningState: NotProvisioned with the following defaults: - Allow Classic Operations: null (disabled) - Rate Limiting: null (disabled) - Location: Uses the location defined in the main configuration

Advanced Configuration

The following example demonstrates both the standard provider model and the ExpressRoute Direct model:

express_route_circuit = {
    # Standard provider model with Premium SKU for global reach
    er01 = {
        resource_group        = "hub"
        service_provider_name = "Equinix"
        peering_location      = "Seattle"
        bandwidth_in_mbps     = 1000

        sku = {
            tier   = "Premium"       # Required for global reach and cross-region VNet connections
            family = "UnlimitedData" # Preferred when monthly traffic exceeds the metered threshold
        }
    }

    # ExpressRoute Direct model (10/100 Gbps port directly from Microsoft)
    er-direct01 = {
        resource_group        = "hub"
        express_route_port_id = "/subscriptions/.../expressRoutePorts/my-er-port"
        bandwidth_in_gbps     = 10

        sku = {
            tier   = "Premium"
            family = "MeteredData"
        }
    }
}

Configuration Parameters

Parameter Type Required Default Description
resource_group string Yes - Key of the resource group where the circuit is deployed
sku object Yes - SKU block defining tier and billing family (see SKU)
service_provider_name string No* null ExpressRoute connectivity provider name (standard model)
peering_location string No* null Provider peering location (standard model). Run az network express-route list-service-providers for valid combinations
bandwidth_in_mbps number No* null Circuit bandwidth in Mbps (standard model). Must be a value supported by the provider at that peering location
express_route_port_id string No† null Resource ID of the ExpressRoute Direct port (Direct model)
bandwidth_in_gbps number No† null Circuit bandwidth in Gbps (Direct model)
allow_classic_operations bool No null Allows management of classic (non-ARM) virtual networks connected to this circuit
authorization_key string No null Authorization key for cross-subscription circuit access
rate_limiting_enabled bool No null Enables rate limiting on the circuit
name string No Auto-generated Custom name. If not specified, uses naming convention
location string No Global location Azure region where the circuit is created
timeouts object No null Custom Terraform operation timeouts (create, read, update, delete)
tags map(string) No {} Tags merged with default tags

* Required together for the standard provider model. All three must be provided or all three omitted.
† Required together for the ExpressRoute Direct model. Mutually exclusive with the standard model fields.

SKU

sku = {
    tier   = "Standard"    # Standard or Premium
    family = "MeteredData" # MeteredData or UnlimitedData
}
Field Type Required Description
tier string Yes Basic — limited, legacy. Local — same-metro circuits, included egress. Standard — up to 10 VNets, same geopolitical region. Premium — unlimited VNets, global reach, cross-region connections

| family | string | Yes | MeteredData — billed per GB of egress. UnlimitedData — flat rate regardless of traffic volume |

Tier comparison:

Feature Standard Premium
VNets per circuit Up to 10 Unlimited
Global reach No Yes
Cross-region VNet connections No Yes
Microsoft peering No Yes

Circuit Provisioning States

A circuit transitions through the following states after creation:

State Meaning
NotProvisioned Circuit created; provider has not begun provisioning
Provisioning Provider is actively configuring the physical connection
Provisioned Provider provisioning complete; circuit is ready for peering and connection
Deprovisioning Provider is removing the physical connection

Azure bills for the circuit in all states. The circuit must reach Provisioned before a Virtual Network Gateway Connection can pass traffic.

Naming Convention

Circuit names are automatically generated using the following pattern:

{name_prefixes.express_route_circuit}{key}{name_suffixes.express_route_circuit}

For example, with the following prefixes and suffixes:

name_prefixes = {
    express_route_circuit = "erc-connect-"
}

name_suffixes = {
    express_route_circuit = "-westus2"
}

express_route_circuit = {
    er01 = {
        resource_group        = "hub"
        service_provider_name = "Equinix"
        peering_location      = "Seattle"
        bandwidth_in_mbps     = 1000
        sku = {
            tier   = "Standard"
            family = "MeteredData"
        }
    }
}

The resulting circuit name would be: erc-connect-er01-westus2

To override automatic naming, specify a custom name:

express_route_circuit = {
    er01 = {
        name                  = "my-expressroute-circuit"
        resource_group        = "hub"
        service_provider_name = "Equinix"
        peering_location      = "Seattle"
        bandwidth_in_mbps     = 1000
        sku = {
            tier   = "Standard"
            family = "MeteredData"
        }
    }
}

Finding Valid Provider and Peering Location Values

Azure validates service_provider_name and peering_location against a catalog of available providers. To list valid combinations:

az network express-route list-service-providers \
    --query "[].{Provider:name, Locations:peeringLocations, Bandwidths:bandwidthsOffered}" \
    --output table

Filter by a specific provider:

az network express-route list-service-providers \
    --query "[?name=='Equinix'].{Locations:peeringLocations, Bandwidths:bandwidthsOffered}"

Best Practices

  1. Delete Test Circuits Promptly: Billing starts on creation. For proof-of-concept deployments, destroy the resource as soon as the deployment is validated — there is no grace period
  2. Standard vs Premium: Use Standard unless you need global reach, Microsoft peering, or connections to VNets outside the circuit's geopolitical region
  3. MeteredData vs UnlimitedData: Compare your expected monthly egress (GB) against the pricing difference between the two families — UnlimitedData is only cost-effective at high traffic volumes
  4. Two Circuits for Resilience: A single circuit is a single point of failure regardless of the gateway SKU. Deploy two circuits from different peering locations and connect both to the same ExpressRoute gateway for true redundancy
  5. Match Gateway SKU to Circuit Bandwidth: The ExpressRoute gateway must be sized to match the circuit bandwidth — ErGw1AZ supports up to 1 Gbps, ErGw2AZ up to 2 Gbps, ErGw3AZ up to 10 Gbps. Under-sizing the gateway causes dropped traffic
  6. Share the Service Key: After terraform apply, retrieve the circuit's service key from the Azure portal or via az network express-route show and provide it to your connectivity provider to begin physical provisioning
  7. Premium for Global Reach: If you plan to use ExpressRoute Global Reach (connecting two on-premises sites through Azure without backhauling through a VNet), both circuits must use the Premium tier