Azure Virtual WAN module creates a Virtual WAN with a Virtual Hub, an Azure Firewall and an Express Route circuit with its private peering and VPN connections. An infrastructure example referenced in the Azure Cloud Adoption Framework is available here: raw.githubusercontent.com/microsoft/CloudAdoptionFramework/master/ready/enterprise-scale-architecture.pdf
This module use multiple sub-modules:
- Virtual Hub: Manage all Virtual Hub configurations
- Azure Firewall: Manage the creation of Azure Firewall in a Secured Hub
- Azure ExpressRoute: Manage ExpressRoute creation and configuration
- Azure VPN: Manage VPN connection in a Virtual Hub
Resource naming is based on the Microsoft CAF naming convention best practices. Use the parameter var.<resource>_custom_name to override names.
We rely on the forked Claranet Azure CAF naming Terraform provider to generate resources names.
| Module version | Terraform version | OpenTofu version | AzureRM version |
|---|---|---|---|
| >= 8.x.x | Unverified | 1.8.x | >= 4.0 |
| >= 7.x.x | 1.3.x | >= 3.0 | |
| >= 6.x.x | 1.x | >= 3.0 | |
| >= 5.x.x | 0.15.x | >= 2.0 | |
| >= 4.x.x | 0.13.x / 0.14.x | >= 2.0 | |
| >= 3.x.x | 0.12.x | >= 2.0 | |
| >= 2.x.x | 0.12.x | < 2.0 | |
| < 2.x.x | 0.11.x | < 2.0 |
If you want to contribute to this repository, feel free to use our pre-commit git hook configuration which will help you automatically update and format some files for you by enforcing our Terraform code module best-practices.
More details are available in the CONTRIBUTING.md file.
This module is optimized to work with the Claranet terraform-wrapper tool
which set some terraform variables in the environment needed by this module.
More details about variables set by the terraform-wrapper available in the documentation.
module "virtual_wan" {
source = "claranet/virtual-wan/azurerm"
version = "x.x.x"
location = module.azure_region.location
location_short = module.azure_region.location_short
client_name = var.client_name
environment = var.environment
stack = var.stack
resource_group_name = module.rg.name
virtual_hub_address_prefix = "10.254.0.0/23"
peered_virtual_networks = [
for vnet in local.vnets : {
vnet_id = module.vnets[vnet.name].id
internet_security_enabled = vnet.internet_security_enabled
}
]
firewall_enabled = true
express_route_enabled = true
express_route_private_peering_enabled = true
vpn_gateway_enabled = true
express_route_circuit_peering_location = "Paris"
express_route_circuit_bandwidth_in_mbps = 100
express_route_circuit_service_provider = "Equinix"
express_route_private_peering_primary_peer_address_prefix = "169.254.254.0/30"
express_route_private_peering_secondary_peer_address_prefix = "169.254.254.4/30"
express_route_private_peering_shared_key = "MySuperSecretSharedKey"
express_route_private_peering_peer_asn = 4321
express_route_private_peering_vlan_id = 1234
vpn_gateway_instance_0_bgp_peering_address = ["169.254.21.1"]
vpn_gateway_instance_1_bgp_peering_address = ["169.254.22.1"]
vpn_sites = [{
name = "site1"
links = [
{
name = "site1-primary-endpoint"
ip_address = "20.20.20.20"
bgp = [{
asn = 65530
peering_address = "169.254.21.2"
}]
},
{
name = "site1-secondary-endpoint"
ip_address = "21.21.21.21"
bgp = [{
asn = 65530
peering_address = "169.254.22.2"
}]
},
]
}]
vpn_connections = [{
name = "cn-hub-to-site1"
site_name = "site1"
links = [
{
name = "site1-primary-link"
bandwidth_mbps = 200
bgp_enabled = true
protocol = "IKEv2"
shared_key = "VeryStrongSecretKeyForPrimaryLink"
ipsec_policy = {
dh_group = "DHGroup14"
ike_encryption_algorithm = "AES256"
ike_integrity_algorithm = "SHA256"
encryption_algorithm = "AES256"
integrity_algorithm = "SHA256"
pfs_group = "PFS14"
sa_data_size_kb = 102400000
sa_lifetime_sec = 3600
}
},
{
name = "site1-secondary-link"
bandwidth_mbps = 200
bgp_enabled = true
protocol = "IKEv2"
shared_key = "VeryStrongSecretKeyForSecondaryLink"
ipsec_policy = {
dh_group = "DHGroup14"
ike_encryption_algorithm = "AES256"
ike_integrity_algorithm = "SHA256"
encryption_algorithm = "AES256"
integrity_algorithm = "SHA256"
pfs_group = "PFS14"
sa_data_size_kb = 102400000
sa_lifetime_sec = 3600
}
},
]
}]
logs_destinations_ids = [
module.run.log_analytics_workspace_id,
module.run.logs_storage_account_id,
]
}| Name | Version |
|---|---|
| azurecaf | >= 1.2.28 |
| azurerm | ~> 4.31 |
| terraform | n/a |
| Name | Source | Version |
|---|---|---|
| express_route | ./modules/express-route | n/a |
| firewall | ./modules/firewall | n/a |
| routing_intent | ./modules/routing-intent | n/a |
| virtual_hub | ./modules/virtual-hub | n/a |
| vpn | ./modules/vpn | n/a |
| Name | Type |
|---|---|
| azurerm_virtual_wan.main | resource |
| terraform_data.routing_intent_precondition | resource |
| azurecaf_name.main | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| azure_firewall_as_next_hop_enabled | Whether use Azure Firewall as next hop or a NVA. | bool |
true |
no |
| branch_to_branch_traffic_allowed | Boolean flag to specify whether branch to branch traffic is allowed. | bool |
true |
no |
| client_name | Client name/account used in naming. | string |
n/a | yes |
| custom_name | Custom Virtual WAN name. | string |
null |
no |
| default_tags_enabled | Option to enabled or disable default tags | bool |
true |
no |
| environment | Project environment. | string |
n/a | yes |
| express_route_circuit_bandwidth_in_mbps | The bandwidth in Mbps of the Express Route circuit being created on the service provider. | number |
null |
no |
| express_route_circuit_custom_name | Custom Express Route circuit name. | string |
null |
no |
| express_route_circuit_enabled | Whether or not to create the Express Route circuit. | bool |
true |
no |
| express_route_circuit_peering_location | Express Route circuit peering location. | string |
null |
no |
| express_route_circuit_service_provider | The name of the Express Route circuit service provider. | string |
null |
no |
| express_route_circuit_sku | Express Route circuit SKU. | object({ |
{ |
no |
| express_route_diagnostic_settings_custom_name | Custom name of the diagnostic settings. Defaults to default. |
string |
"default" |
no |
| express_route_enabled | Enable or disable Express Route. | bool |
false |
no |
| express_route_extra_tags | Extra tags for the Express Route. | map(string) |
null |
no |
| express_route_gateway_custom_name | Custom Express Route gateway name. | string |
null |
no |
| express_route_gateway_non_virtual_wan_traffic_allowed | Whether the gateway accepts traffic from non-Virtual WAN networks. | bool |
false |
no |
| express_route_gateway_scale_unit | The number of scale units with which to provision the Express Route gateway. | number |
1 |
no |
| express_route_logs_categories | Log categories to send to destinations. | list(string) |
null |
no |
| express_route_logs_destinations_ids | List of destination resources IDs for logs diagnostic destination. Can be Storage Account, Log Analytics Workspace and Event Hub. No more than one of each can be set.If you want to use Azure EventHub as a destination, you must provide a formatted string containing both the EventHub Namespace authorization send ID and the EventHub name (name of the queue to use in the Namespace) separated by the | character. |
list(string) |
null |
no |
| express_route_logs_metrics_categories | Metrics categories to send to destinations. | list(string) |
null |
no |
| express_route_private_peering_enabled | Whether or not to enable private peering on the Express Route circuit. | bool |
false |
no |
| express_route_private_peering_peer_asn | Peer BGP ASN for the Express Route circuit private peering. | number |
null |
no |
| express_route_private_peering_primary_peer_address_prefix | Primary peer address prefix for the Express Route circuit private peering. | string |
null |
no |
| express_route_private_peering_secondary_peer_address_prefix | Secondary peer address prefix for the Express Route circuit private peering. | string |
null |
no |
| express_route_private_peering_shared_key | Shared secret key for the Express Route circuit private peering. | string |
null |
no |
| express_route_private_peering_vlan_id | VLAN ID for the Express Route circuit. | number |
null |
no |
| extra_tags | Map of additional tags. | map(string) |
null |
no |
| firewall_custom_name | Custom firewall name. | string |
null |
no |
| firewall_diagnostic_settings_custom_name | Custom name of the diagnostic settings. Defaults to default. |
string |
"default" |
no |
| firewall_dns_servers | List of DNS servers that the firewall will redirect DNS traffic to for the name resolution. | list(string) |
null |
no |
| firewall_enabled | Enable or disable Azure Firewall in the Virtual Hub. | bool |
true |
no |
| firewall_extra_tags | Extra tags for the firewall. | map(string) |
null |
no |
| firewall_logs_categories | Log categories to send to destinations. | list(string) |
null |
no |
| firewall_logs_destinations_ids | List of destination resources IDs for logs diagnostic destination. Can be Storage Account, Log Analytics Workspace and Event Hub. No more than one of each can be set.If you want to use Azure EventHub as a destination, you must provide a formatted string containing both the EventHub Namespace authorization send ID and the EventHub name (name of the queue to use in the Namespace) separated by the | character. |
list(string) |
null |
no |
| firewall_logs_metrics_categories | Metrics categories to send to destinations. | list(string) |
null |
no |
| firewall_policy | ID of the firewall policy applied to this firewall. | object({ |
null |
no |
| firewall_private_ip_ranges | List of SNAT private IP ranges, or the special string IANAPrivateRanges, which indicates the firewall does not SNAT when the destination IP address is a private range per IANA RFC 1918. |
list(string) |
null |
no |
| firewall_public_ip_count | Number of public IPs to assign to the firewall. | number |
1 |
no |
| firewall_sku_tier | SKU tier of the firewall. Possible values are Premium and Standard. |
string |
"Standard" |
no |
| firewall_zones | Availability zones in which the firewall should be created. | list(number) |
[ |
no |
| internet_routing_enabled | Whether force the internet routing through Azure Firewall or the NVA. | bool |
true |
no |
| internet_security_enabled | Define internet security parameter in both VPN connections and Virtual Hub connections. | bool |
null |
no |
| location | Azure location. | string |
n/a | yes |
| location_short | Short string for Azure location. | string |
n/a | yes |
| logs_destinations_ids | List of destination resources IDs for logs diagnostic destination. Can be Storage Account, Log Analytics Workspace and Event Hub. No more than one of each can be set.If you want to use Azure EventHub as a destination, you must provide a formatted string containing both the EventHub Namespace authorization send ID and the EventHub name (name of the queue to use in the Namespace) separated by the | character. |
list(string) |
n/a | yes |
| name_prefix | Prefix for generated resources names. | string |
"" |
no |
| name_slug | Slug to use with generated resources names. | string |
"" |
no |
| name_suffix | Suffix for generated resources names. | string |
"" |
no |
| nat_rules | List of NAT rules to apply to the VPN Gateway. For dynamic NAT rules, if ip_configuration_name is not set, the first IP configuration will be used. |
list(object({ |
[] |
no |
| next_hop_nva_id | ID of the NVA used as next hop. | string |
null |
no |
| office365_local_breakout_category | Specifies the Office365 local breakout category. Possible values are Optimize, OptimizeAndAllow, All and None. Defaults to None. |
string |
"None" |
no |
| peered_virtual_networks | List of Virtual Network objects to peer with the Virtual Hub. | list(object({ |
[] |
no |
| private_routing_enabled | Whether force the private routing through Azure Firewall or the NVA. | bool |
true |
no |
| resource_group_name | Resource Group name. | string |
n/a | yes |
| routing_intent_custom_name | Custom routing intent name. hubRoutingIntent if not set. |
string |
null |
no |
| routing_intent_enabled | Enable or disable routing intent feature in the Virtual Hub. | bool |
false |
no |
| stack | Project Stack name. | string |
n/a | yes |
| type | Specifies the Virtual WAN type. Possible Values are Basic and Standard. Defaults to Standard. |
string |
"Standard" |
no |
| virtual_hub_address_prefix | The address prefix which should be used for this Virtual Hub. Cannot be smaller than a /24. A /23 is recommended by Azure. | string |
n/a | yes |
| virtual_hub_custom_name | Custom Virtual Hub name. | string |
null |
no |
| virtual_hub_extra_tags | Extra tags for the Virtual Hub. | map(string) |
null |
no |
| virtual_hub_routes | List of route objects. var.routes[*].next_hop_ip_address values can be azure_firewall or an IP address. |
list(object({ |
[] |
no |
| virtual_hub_sku | The SKU of the Virtual Hub. Possible values are Basic and Standard. |
string |
"Standard" |
no |
| virtual_wan_extra_tags | Extra tags for this Virtual WAN. | map(string) |
null |
no |
| vpn_connections | VPN connections configuration. | list(object({ |
[] |
no |
| vpn_encryption_enabled | Boolean flag to specify whether VPN encryption is enabled. | bool |
true |
no |
| vpn_gateway_bgp_peer_weight | The weight added to routes learned from this BGP speaker. | number |
0 |
no |
| vpn_gateway_custom_name | Custom VPN gateway name. | string |
null |
no |
| vpn_gateway_diagnostic_settings_custom_name | Custom name of the diagnostic settings. Defaults to default. |
string |
"default" |
no |
| vpn_gateway_enabled | Whether or not to enable the deployment of a VPN gateway and its connections. | bool |
false |
no |
| vpn_gateway_extra_tags | Extra tags for the VPN gateway. | map(string) |
null |
no |
| vpn_gateway_instance_0_bgp_peering_address | List of custom BGP IP addresses to assign to the first instance. | list(string) |
[] |
no |
| vpn_gateway_instance_1_bgp_peering_address | List of custom BGP IP addresses to assign to the second instance. | list(string) |
[] |
no |
| vpn_gateway_logs_categories | Log categories to send to destinations. | list(string) |
null |
no |
| vpn_gateway_logs_destinations_ids | List of destination resources IDs for logs diagnostic destination. Can be Storage Account, Log Analytics Workspace and Event Hub. No more than one of each can be set.If you want to use Azure EventHub as a destination, you must provide a formatted string containing both the EventHub Namespace authorization send ID and the EventHub name (name of the queue to use in the Namespace) separated by the | character. |
list(string) |
null |
no |
| vpn_gateway_logs_metrics_categories | Metrics categories to send to destinations. | list(string) |
null |
no |
| vpn_gateway_routing_preference | Azure routing preference. You can choose to route traffic either via the Microsoft network (set to Microsoft network) or via the ISP network (set to Internet). |
string |
"Microsoft Network" |
no |
| vpn_gateway_scale_unit | The scale unit for this VPN gateway. | number |
1 |
no |
| vpn_sites | VPN sites configuration. | list(object({ |
[] |
no |
| Name | Description |
|---|---|
| express_route_circuit_id | ID of the Express Route circuit. |
| express_route_circuit_name | Name of the Express Route circuit. |
| express_route_circuit_service_key | The string needed by the service provider to provision the Express Route circuit. |
| express_route_circuit_service_provider_provisioning_state | The Express Route circuit provisioning state from your chosen service provider. |
| express_route_gateway_id | ID of the Express Route gateway. |
| express_route_gateway_name | Name of the Express Route gateway. |
| express_route_private_peering_azure_asn | Autonomous System Number used by Azure for BGP peering. |
| firewall_id | ID of the firewall. |
| firewall_ip_configuration | IP configuration of the firewall. |
| firewall_management_ip_configuration | Management IP configuration of the firewall. |
| firewall_name | Name of the firewall. |
| firewall_private_ip_address | Private IP address of the firewall. |
| firewall_public_ip_addresses | Public IP addresses of the firewall. |
| id | ID of the Virtual WAN. |
| module_express_route | Express Route module outputs. |
| module_firewall | Firewall module outputs. |
| module_routing_intent | Routing intent module outputs. |
| module_virtual_hub | Virtual Hub module outputs. |
| module_vpn | VPN module outputs. |
| name | Name of the Virtual WAN. |
| resource | Virtual WAN resource object. |
| routing_intent_id | ID of the routing intent. |
| routing_intent_name | Name of the routing intent. |
| terraform_module | Information about this Terraform module. |
| virtual_hub_default_route_table_id | ID of the default route table associated with the Virtual Hub. |
| virtual_hub_id | ID of the Virtual Hub. |
| virtual_hub_name | Name of the Virtual Hub. |
| vpn_gateway_bgp_settings | BGP settings of the VPN gateway. |
| vpn_gateway_connections_ids | Map of VPN gateway connections (name => ID). |
| vpn_gateway_id | ID of the VPN gateway. |
| vpn_gateway_name | Name of the VPN gateway. |
- Azure Virtual WAN: learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-about
- Azure Firewall: learn.microsoft.com/en-us/azure/firewall/overview
- Azure Express Route circuit: learn.microsoft.com/en-us/azure/expressroute/expressroute-circuit-peerings