Connect Azure VMware Solution with Virtual WAN via ExpressRoute using Terraform

4 min read
By prox

In case if you're developing your infrastructure as a code with Terraform and you need to connect your Azure VMware Solution (AVS) cluster to the Virtual WAN hub using ExpressRoute connection, you can follow the steps described in this article.


You need to have:

  • Deployed AVS cluster
  • Deployed Azure Virtual WAN
  • Deployed Azure Virtual WAN Hub

In case you also want to declare these resources in your code (which in most cases you do), then here are the examples of their definition:

# Variables

variable "region" {
  description = "Region in which resources located"
  type        = string
  default     = "West Europe"

variable "resource_group_name" {
  description = "Name of the resource group"
  type        = string
  default     = "rg-dc-net"

variable "tags" {
  description = "Map of tags to apply to the resources"
  type        = map(string)
  default     = {
    "Environment" = "prod"
    "Project"     = "network"

variable "dc_ident" {
  description = "Unique identifier of the datacenter"
  type        = string
  default     = "dc"

variable "vwan_ident" {
  description = "Unique identifier of the vWAN instance"
  type        = string
  default     = "core"

variable "vhub_ident" {
  description = "Unique identifier of the vWAN Hub instance"
  type        = string
  default     = "hub01"

variable "vhub_cidr" {
  description = "CIDR for vWAN Hub instance (/24 or greater)"
  type        = string
  default     = ""

# Locals

locals {
  vwan_name        = "vwan-${var.dc_ident}-${var.vwan_ident}"
  vhub_name        = "vhub-${var.dc_ident}-${var.vwan_ident}-${var.vhub_ident}"
  exr_gateway_name = "ergw-${var.dc_ident}-${var.vwan_ident}-${var.vhub_ident}"

# Virtual WAN
resource "azurerm_virtual_wan" "vwan" {
  name                = local.vwan_name
  resource_group_name = var.resource_group_name
  location            = var.region
  tags                = var.tags

# Virtual WAN Hub
resource "azurerm_virtual_hub" "vhub" {
  name                = local.vhub_name
  resource_group_name = var.resource_group_name
  location            = var.region
  virtual_wan_id      =
  address_prefix      = var.vhub_cidr
  tags                = var.tags

For convenience, the sample code is split into three files. In the first one, we declare the variables we will use further, next declare local definitions of the object names and then declare all resources related to Virtual WAN.

By default, the virtual hub router is automatically configured to deploy with a virtual hub capacity of 2 routing infrastructure units. This supports a minimum of 3 Gbps aggregate throughput, and 2000 connected VMs deployed in all virtual networks connected to that virtual hub.

If you want to change the performance of the vWAN Hub, you can add a virtual_router_auto_scale_min_capacity parameter to the Hub definition. For supported values please refer to the Azure Virtual Hub settings documentation.

Add an ExpressRoute gateway instance

To connect the AVS cluster to vWAN, you will need an ExpressRoute gateway instance.

Let's add an ExR Gateway definition to the file:

<... omitted ...>

# ExR Gateway
resource "azurerm_express_route_gateway" "vhub_exr_gateway" {
  name                = local.exr_gateway_name
  resource_group_name = var.resource_group_name
  location            = var.region
  virtual_hub_id      =
  scale_units         = 1
  tags                = var.tags

Same as for vWAN Hub, the ExpressRoute gateway has its performance parameter called scale_units. To learn more about the ExR Gateway scale units, please refer to the ExpressRoute Gateway performance in Virtual WAN documentation.

Obtain AVS ExpressRoute peering ID

Before we can proceed and declare the connection resource, first we need to get the AVS ExR private peering ID. In my case, the AVS cluster was deployed as a separate project, so there's no AVS cluster resource definition. Thus you can use the data resource to get it. Add a few more variables to the that will describe where the AVS cluster is deployed and what's its name:

<... omitted ...>

variable "avs_cluster_resource_group_name" {
  description = "Name of the resource group where AVS cluster deployed"
  type        = string
  default     = "rg-dc-avs"

variable "avs_cluster_name" {
  description = "Name of the AVS cluster"
  type        = string
  default     = "avs-dc-cluster"

Now create another file named and add the data resource:

data "azurerm_vmware_private_cloud" "avs_cluster" {
  name                = var.avs_cluster_name
  resource_group_name = var.avs_cluster_resource_group_name

Generate ExR authorization key

As stated earlier, in my case the AVS cluster was deployed separately, therefore another step has to be done - is to request an ExpressRoute authorization key. This key is then used as a parameter in the ExpressRoute connection resource.

If you're deploying vWAN and AVS cluster altogether, you can declare a azurerm_vmware_express_route_authorization resource the required number of times to get authorization keys.

You can ask a person responsible for AVS cluster administration to generate that key for you. Or, if you have enough privileges, generate such a key yourself. To do that:

  • proceed to the Azure Portal
  • in the search bar type avs
  • click on the Azure VMware Solution item
  • you should see the list of available AVS clusters (if not, verify you have the right subscription selected)
  • click on the target cluster from the list
  • on the left pane click on Manage > Connectivity and then
  • select the ExpressRoute in the middle pane
  • click on Request an Authorization key
  • enter the recognizable name for the key (it could be the name of your vWAN Hub for example)
  • click on the Create button and wait until the key is generated

The key will be displayed in the middle pane in a Name/Key table.

Screenshot shows how to request an ExpressRoute authorization key.

Add an authorization key variable and the ExR connection name to the

<... omitted ...>

variable "avs_exr_auth_key" {
  description = "Authorization key for the ExpressRoute connection to AVS"
  type        = string

variable "vhub_exr_connection_name" {
  description = "Name of the AVS connection in ExR gateway"
  type = string
  default = "erc-avs-dc-cluster"

Declare ExR connection

Head to the file and add the next lines:

<... omitted ...>

# ExR connection
resource "azurerm_express_route_connection" "erc_avs_private_cloud" {
  name                             = var.vhub_exr_connection_name
  express_route_gateway_id         =
  express_route_circuit_peering_id = data.azurerm_vmware_private_cloud.avs_cluster.circuit[0].express_route_private_peering_id
  authorization_key                = var.avs_exr_auth_key

This way we declared the ExpressRoute connection from vWAN Hub (ExR Gateway) to the AVS cluster.

Create resources

Run terrafrom apply to calculate the differences and create the required resources.

Related Articles