Skip to content

Commit

Permalink
Add VPN Gateway NAT Rules module (aztfmod#1923)
Browse files Browse the repository at this point in the history
* add bgp_route_translation_for_nat_enabled parameter

* Add VPN Gateway NAT rules

* move example to longrun

* Fix nat rule description
  • Loading branch information
trapeznikov authored and MarcelHeek committed May 28, 2024
1 parent 2bcc5e9 commit 406941a
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/standalone-scenarios-longrunners.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"networking/virtual_wan/104-vwan-hub-gw-spp",
"networking/virtual_wan/105-vwan-hub-route-table",
"networking/virtual_wan/109-vwan-vpn-gateway-connection",
"networking/virtual_wan/110-vwan-hub-gw-p2s-keyvault-cert",
"networking/virtual_wan/111-vwan-vpn-gateway-connection-with-nat",
"redis_cache/100-redis-standard",
"redis_cache/101-redis-diagnostics",
"redis_cache/102-redis-private",
Expand Down
1 change: 1 addition & 0 deletions examples/module.tf
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ module "example" {
vnets = var.vnets
virtual_subnets = var.virtual_subnets
vpn_gateway_connections = var.vpn_gateway_connections
vpn_gateway_nat_rules = var.vpn_gateway_nat_rules
vpn_sites = var.vpn_sites
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
global_settings = {
default_region = "region1"
regions = {
region1 = "australiaeast"
}
}

resource_groups = {
hub_re1 = {
name = "vnet-hub-re1"
region = "region1"
}
}

virtual_wans = {
vwan_re1 = {
resource_group_key = "hub_re1"
name = "contosovWAN-re1"
region = "region1"

hubs = {
hub_re1 = {
hub_name = "hub-re1"
region = "region1"
hub_address_prefix = "10.0.3.0/24"
deploy_p2s = false
p2s_config = {}
deploy_s2s = true
s2s_config = {
name = "caf-sea-vpn-s2s"
scale_unit = 1
bgp_route_translation_for_nat_enabled = true
}
deploy_er = false
}
}
}
}

virtual_hub_route_tables = {
routetable1 = {
name = "example-vhubroutetable1"

virtual_wan_key = "vwan_re1"
virtual_hub_key = "hub_re1"

labels = ["label1"]
}
routetable2 = {
name = "example-vhubroutetable2"

virtual_wan_key = "vwan_re1"
virtual_hub_key = "hub_re1"

labels = ["label2"]
}
}

vpn_sites = {
vpn-site-1 = {
name = "vpn-site-1"
address_cidrs = ["1.2.3.0/24", "4.5.6.0/24"]
device_vendor = "Cisco"
device_model = "800"

resource_group = {
key = "hub_re1"
}

virtual_wan = {
key = "vwan_re1"
}

links = {
primary = {
name = "primary"
ip_address = "1.2.3.4"
provider_name = "Microsoft"
speed_in_mbps = "150"
}
secondary = {
name = "secondary"
fqdn = "secondary.link.com"
provider_name = "Microsoft"
speed_in_mbps = "50"
# bgp = {
# asn = "65534"
# peering_address = "169.254.1.2"
# }
}
}
}
}

vpn_gateway_connections = {
connection-1 = {
name = "connection-1"
internet_security_enabled = false

# vpn_site_id = "" # Set the Resource ID of an existing VPN Site
vpn_site = {
# lz_key = "vpns" # Set the 'lz_key' of a VPN Site created in a remote deployment
key = "vpn-site-1" # Set the 'key' of the VPN Site created in this (or a remote) deployment
}
virtual_wan = {
key = "vwan_re1"
}
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
virtual_hub = {
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
}

vpn_links = {
link-1 = {
link_index = 0 # Index order of VPN Site's Link
name = "link-1"
bandwidth_mbps = "100" # Optional
bgp_enabled = false # Optional
protocol = "IKEv2" # Optional
ratelimit_enabled = true # Optional
route_weight = "100" # Optional
shared_key = "abc123456" # Optional
local_azure_ip_address_enabled = false # Optional
policy_based_traffic_selectors_enabled = false # Optional

egress_nat_rules = { # Optional
rule-1 = {
key = "rule-1"
}
}
ingress_nat_rules = { # Optional
rule-2 = {
key = "rule-2"
}
}
ipsec_policies = { # Optional
policy1 = {
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 = "27000"
}
}
}
# link-2 = {
# link_index = 1
# name = "link-2"
# }
}

}
}

vpn_gateway_nat_rules = {
rule-1 = {
resource_group_key = "hub_re1"
name = "rule-1"

virtual_wan = {
key = "vwan_re1"
}
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
virtual_hub = {
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
}

internal_mapping = {
imap-1 = {
address_space = "192.168.41.0/26"
}
}

external_mapping = {
emap-1 = {
address_space = "192.168.45.0/26"
}
}
mode = "EgressSnat"
type = "Static"
}
rule-2 = {
resource_group_key = "hub_re1"
name = "rule-2"

virtual_wan = {
key = "vwan_re1"
}
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
virtual_hub = {
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
}

internal_mapping = {
imap-1 = {
address_space = "192.168.21.0/26"
}
}

external_mapping = {
emap-1 = {
address_space = "192.168.25.0/26"
}
}
mode = "IngressSnat"
type = "Static"
}
rule-3 = {
resource_group_key = "hub_re1"
name = "rule-3"

virtual_wan = {
key = "vwan_re1"
}
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
virtual_hub = {
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
}
ip_configuration_id = "Instance0"
internal_mapping = {
imap-1 = {
address_space = "192.168.26.0/26"
}
imap-2 = {
address_space = "192.168.31.0/26"
}
}

external_mapping = {
emap-1 = {
address_space = "192.168.27.0/26"
}
emap-2 = {
address_space = "192.168.35.0/26"
}
}
mode = "IngressSnat"
type = "Dynamic"
}
}
3 changes: 3 additions & 0 deletions examples/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,9 @@ variable "vpn_sites" {
variable "vpn_gateway_connections" {
default = {}
}
variable "vpn_gateway_nat_rules" {
default = {}
}
variable "servicebus_namespaces" {
default = {}
}
Expand Down
1 change: 1 addition & 0 deletions local.remote_objects.tf
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ locals {
vmware_express_route_authorizations = try(local.combined_objects_vmware_express_route_authorizations, null)
vmware_private_clouds = try(local.combined_objects_vmware_private_clouds, null)
vpn_gateway_connections = try(local.combined_objects_vpn_gateway_connections, null)
vpn_gateway_nat_rules = try(local.combined_objects_vpn_gateway_nat_rules, null)
vpn_sites = try(local.combined_objects_vpn_sites, null)
web_pubsubs = try(local.combined_objects_web_pubsubs, null)
web_pubsub_hubs = try(local.combined_objects_web_pubsub_hubs, null)
Expand Down
1 change: 1 addition & 0 deletions locals.combined_objects.tf
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ locals {
combined_objects_vmware_express_route_authorizations = merge(tomap({ (local.client_config.landingzone_key) = module.vmware_express_route_authorizations }), try(var.remote_objects.vmware_express_route_authorizations, {}))
combined_objects_vmware_private_clouds = merge(tomap({ (local.client_config.landingzone_key) = module.vmware_private_clouds }), try(var.remote_objects.vmware_private_clouds, {}), try(var.data_sources.vmware_private_clouds, {}))
combined_objects_vpn_gateway_connections = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_gateway_connections }), try(var.remote_objects.vpn_gateway_connections, {}))
combined_objects_vpn_gateway_nat_rules = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_gateway_nat_rules }), try(var.remote_objects.vpn_gateway_nat_rules, {}))
combined_objects_vpn_sites = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_sites }), try(var.remote_objects.vpn_sites, {}))
combined_objects_web_pubsub_hubs = merge(tomap({ (local.client_config.landingzone_key) = module.web_pubsub_hubs }), try(var.remote_objects.web_pubsub_hubs, {}))
combined_objects_web_pubsubs = merge(tomap({ (local.client_config.landingzone_key) = module.web_pubsubs }), try(var.remote_objects.web_pubsubs, {}))
Expand Down
1 change: 1 addition & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ locals {
vnet_peerings_v1 = try(var.networking.vnet_peerings_v1, {})
vnets = try(var.networking.vnets, {})
vpn_gateway_connections = try(var.networking.vpn_gateway_connections, {})
vpn_gateway_nat_rules = try(var.networking.vpn_gateway_nat_rules, {})
vpn_sites = try(var.networking.vpn_sites, {})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ resource "azurerm_vpn_gateway" "s2s_gateway" {
tags = local.tags
virtual_hub_id = azurerm_virtual_hub.vwan_hub.id

scale_unit = var.virtual_hub_config.s2s_config.scale_unit
routing_preference = try(var.virtual_hub_config.s2s_config.routing_preference, "Microsoft Network")
scale_unit = var.virtual_hub_config.s2s_config.scale_unit
routing_preference = try(var.virtual_hub_config.s2s_config.routing_preference, "Microsoft Network")
bgp_route_translation_for_nat_enabled = try(var.virtual_hub_config.s2s_config.bgp_route_translation_for_nat_enabled, false)

dynamic "bgp_settings" {
for_each = try(var.virtual_hub_config.s2s_config.bgp_settings, null) == null ? [] : [1]
Expand Down Expand Up @@ -55,4 +56,4 @@ resource "azurerm_vpn_gateway" "s2s_gateway" {
create = "120m"
delete = "120m"
}
}
}
12 changes: 12 additions & 0 deletions modules/networking/vpn_gateway_connection/module.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ resource "azurerm_vpn_gateway_connection" "vpn_gateway_connection" {
shared_key = try(vpn_link.value.shared_key, null)
local_azure_ip_address_enabled = try(vpn_link.value.local_azure_ip_address_enabled, null)
policy_based_traffic_selector_enabled = try(vpn_link.value.policy_based_traffic_selector_enabled, null)
egress_nat_rule_ids = try(compact(
[
for key, value in vpn_link.value.egress_nat_rules :
can(value.id) ? value.id : var.nat_rules[try(value.lz_key, var.client_config.landingzone_key)][value.key].id
]
), [])
ingress_nat_rule_ids = try(compact(
[
for key, value in vpn_link.value.ingress_nat_rules :
can(value.id) ? value.id : var.nat_rules[try(value.lz_key, var.client_config.landingzone_key)][value.key].id
]
), [])

vpn_site_link_id = coalesce(
try(var.vpn_sites[try(var.settings.vpn_site.lz_key, var.client_config.landingzone_key)][var.settings.vpn_site.key].vpn_site.link[vpn_link.value.link_index].id, null),
Expand Down
1 change: 1 addition & 0 deletions modules/networking/vpn_gateway_connection/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ variable "vpn_gateway_id" {}
variable "vpn_sites" {}
variable "client_config" {}
variable "route_tables" {}
variable "nat_rules" {}
7 changes: 7 additions & 0 deletions modules/networking/vpn_gateway_nat_rule/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_providers {
azurecaf = {
source = "aztfmod/azurecaf"
}
}
}
27 changes: 27 additions & 0 deletions modules/networking/vpn_gateway_nat_rule/module.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
resource "azurerm_vpn_gateway_nat_rule" "vpn_gateway_nat_rule" {
name = var.settings.name
resource_group_name = var.resource_group_name
vpn_gateway_id = var.vpn_gateway_id
ip_configuration_id = try(var.settings.ip_configuration_id, null)

mode = var.settings.mode
type = var.settings.type

dynamic "external_mapping" {
for_each = try(var.settings.external_mapping, {})

content {
address_space = external_mapping.value.address_space
port_range = try(external_mapping.value.port_range, null)
}
}

dynamic "internal_mapping" {
for_each = try(var.settings.internal_mapping, {})

content {
address_space = internal_mapping.value.address_space
port_range = try(internal_mapping.value.port_range, null)
}
}
}
4 changes: 4 additions & 0 deletions modules/networking/vpn_gateway_nat_rule/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "id" {
value = azurerm_vpn_gateway_nat_rule.vpn_gateway_nat_rule.id
description = "Resource ID of the VPN Gateway NAT rule"
}
10 changes: 10 additions & 0 deletions modules/networking/vpn_gateway_nat_rule/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
variable "settings" {}
variable "global_settings" {
description = "Global settings object (see module README.md)"
}
variable "vpn_gateway_id" {}
variable "resource_group_name" {
description = "(Required) The name of the resource group where to create the resource."
type = string
}
variable "client_config" {}
Loading

0 comments on commit 406941a

Please sign in to comment.