Skip to content

Commit 6332886

Browse files
authored
Add VPN Gateway NAT Rules module (#1923)
* add bgp_route_translation_for_nat_enabled parameter * Add VPN Gateway NAT rules * move example to longrun * Fix nat rule description
1 parent 5b85b6e commit 6332886

File tree

16 files changed

+344
-3
lines changed

16 files changed

+344
-3
lines changed

.github/workflows/standalone-scenarios-longrunners.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"networking/virtual_wan/105-vwan-hub-route-table",
3232
"networking/virtual_wan/109-vwan-vpn-gateway-connection",
3333
"networking/virtual_wan/110-vwan-hub-gw-p2s-keyvault-cert",
34+
"networking/virtual_wan/111-vwan-vpn-gateway-connection-with-nat",
3435
"redis_cache/100-redis-standard",
3536
"redis_cache/101-redis-diagnostics",
3637
"redis_cache/102-redis-private",

examples/module.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ module "example" {
265265
vnets = var.vnets
266266
virtual_subnets = var.virtual_subnets
267267
vpn_gateway_connections = var.vpn_gateway_connections
268+
vpn_gateway_nat_rules = var.vpn_gateway_nat_rules
268269
vpn_sites = var.vpn_sites
269270
}
270271

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
global_settings = {
2+
default_region = "region1"
3+
regions = {
4+
region1 = "australiaeast"
5+
}
6+
}
7+
8+
resource_groups = {
9+
hub_re1 = {
10+
name = "vnet-hub-re1"
11+
region = "region1"
12+
}
13+
}
14+
15+
virtual_wans = {
16+
vwan_re1 = {
17+
resource_group_key = "hub_re1"
18+
name = "contosovWAN-re1"
19+
region = "region1"
20+
21+
hubs = {
22+
hub_re1 = {
23+
hub_name = "hub-re1"
24+
region = "region1"
25+
hub_address_prefix = "10.0.3.0/24"
26+
deploy_p2s = false
27+
p2s_config = {}
28+
deploy_s2s = true
29+
s2s_config = {
30+
name = "caf-sea-vpn-s2s"
31+
scale_unit = 1
32+
bgp_route_translation_for_nat_enabled = true
33+
}
34+
deploy_er = false
35+
}
36+
}
37+
}
38+
}
39+
40+
virtual_hub_route_tables = {
41+
routetable1 = {
42+
name = "example-vhubroutetable1"
43+
44+
virtual_wan_key = "vwan_re1"
45+
virtual_hub_key = "hub_re1"
46+
47+
labels = ["label1"]
48+
}
49+
routetable2 = {
50+
name = "example-vhubroutetable2"
51+
52+
virtual_wan_key = "vwan_re1"
53+
virtual_hub_key = "hub_re1"
54+
55+
labels = ["label2"]
56+
}
57+
}
58+
59+
vpn_sites = {
60+
vpn-site-1 = {
61+
name = "vpn-site-1"
62+
address_cidrs = ["1.2.3.0/24", "4.5.6.0/24"]
63+
device_vendor = "Cisco"
64+
device_model = "800"
65+
66+
resource_group = {
67+
key = "hub_re1"
68+
}
69+
70+
virtual_wan = {
71+
key = "vwan_re1"
72+
}
73+
74+
links = {
75+
primary = {
76+
name = "primary"
77+
ip_address = "1.2.3.4"
78+
provider_name = "Microsoft"
79+
speed_in_mbps = "150"
80+
}
81+
secondary = {
82+
name = "secondary"
83+
fqdn = "secondary.link.com"
84+
provider_name = "Microsoft"
85+
speed_in_mbps = "50"
86+
# bgp = {
87+
# asn = "65534"
88+
# peering_address = "169.254.1.2"
89+
# }
90+
}
91+
}
92+
}
93+
}
94+
95+
vpn_gateway_connections = {
96+
connection-1 = {
97+
name = "connection-1"
98+
internet_security_enabled = false
99+
100+
# vpn_site_id = "" # Set the Resource ID of an existing VPN Site
101+
vpn_site = {
102+
# lz_key = "vpns" # Set the 'lz_key' of a VPN Site created in a remote deployment
103+
key = "vpn-site-1" # Set the 'key' of the VPN Site created in this (or a remote) deployment
104+
}
105+
virtual_wan = {
106+
key = "vwan_re1"
107+
}
108+
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
109+
virtual_hub = {
110+
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
111+
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
112+
}
113+
114+
vpn_links = {
115+
link-1 = {
116+
link_index = 0 # Index order of VPN Site's Link
117+
name = "link-1"
118+
bandwidth_mbps = "100" # Optional
119+
bgp_enabled = false # Optional
120+
protocol = "IKEv2" # Optional
121+
ratelimit_enabled = true # Optional
122+
route_weight = "100" # Optional
123+
shared_key = "abc123456" # Optional
124+
local_azure_ip_address_enabled = false # Optional
125+
policy_based_traffic_selectors_enabled = false # Optional
126+
127+
egress_nat_rules = { # Optional
128+
rule-1 = {
129+
key = "rule-1"
130+
}
131+
}
132+
ingress_nat_rules = { # Optional
133+
rule-2 = {
134+
key = "rule-2"
135+
}
136+
}
137+
ipsec_policies = { # Optional
138+
policy1 = {
139+
dh_group = "DHGroup14"
140+
ike_encryption_algorithm = "AES256"
141+
ike_integrity_algorithm = "SHA256"
142+
encryption_algorithm = "AES256"
143+
integrity_algorithm = "SHA256"
144+
pfs_group = "PFS14"
145+
sa_data_size_kb = "102400000"
146+
sa_lifetime_sec = "27000"
147+
}
148+
}
149+
}
150+
# link-2 = {
151+
# link_index = 1
152+
# name = "link-2"
153+
# }
154+
}
155+
156+
}
157+
}
158+
159+
vpn_gateway_nat_rules = {
160+
rule-1 = {
161+
resource_group_key = "hub_re1"
162+
name = "rule-1"
163+
164+
virtual_wan = {
165+
key = "vwan_re1"
166+
}
167+
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
168+
virtual_hub = {
169+
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
170+
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
171+
}
172+
173+
internal_mapping = {
174+
imap-1 = {
175+
address_space = "192.168.41.0/26"
176+
}
177+
}
178+
179+
external_mapping = {
180+
emap-1 = {
181+
address_space = "192.168.45.0/26"
182+
}
183+
}
184+
mode = "EgressSnat"
185+
type = "Static"
186+
}
187+
rule-2 = {
188+
resource_group_key = "hub_re1"
189+
name = "rule-2"
190+
191+
virtual_wan = {
192+
key = "vwan_re1"
193+
}
194+
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
195+
virtual_hub = {
196+
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
197+
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
198+
}
199+
200+
internal_mapping = {
201+
imap-1 = {
202+
address_space = "192.168.21.0/26"
203+
}
204+
}
205+
206+
external_mapping = {
207+
emap-1 = {
208+
address_space = "192.168.25.0/26"
209+
}
210+
}
211+
mode = "IngressSnat"
212+
type = "Static"
213+
}
214+
rule-3 = {
215+
resource_group_key = "hub_re1"
216+
name = "rule-3"
217+
218+
virtual_wan = {
219+
key = "vwan_re1"
220+
}
221+
# virtual_hub_gateway_id = "" # Set the Resource ID of an existing Virtual Hub's VPN Gateway
222+
virtual_hub = {
223+
# lz_key = "" # Set the 'lz_key' of a Virtual Hub created in a remote deployment
224+
key = "hub_re1" # Set the 'key' of the Virtual Hub created in this (or a remote) deployment
225+
}
226+
ip_configuration_id = "Instance0"
227+
internal_mapping = {
228+
imap-1 = {
229+
address_space = "192.168.26.0/26"
230+
}
231+
imap-2 = {
232+
address_space = "192.168.31.0/26"
233+
}
234+
}
235+
236+
external_mapping = {
237+
emap-1 = {
238+
address_space = "192.168.27.0/26"
239+
}
240+
emap-2 = {
241+
address_space = "192.168.35.0/26"
242+
}
243+
}
244+
mode = "IngressSnat"
245+
type = "Dynamic"
246+
}
247+
}

examples/variables.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,9 @@ variable "vpn_sites" {
640640
variable "vpn_gateway_connections" {
641641
default = {}
642642
}
643+
variable "vpn_gateway_nat_rules" {
644+
default = {}
645+
}
643646
variable "servicebus_namespaces" {
644647
default = {}
645648
}

local.remote_objects.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ locals {
136136
vmware_express_route_authorizations = try(local.combined_objects_vmware_express_route_authorizations, null)
137137
vmware_private_clouds = try(local.combined_objects_vmware_private_clouds, null)
138138
vpn_gateway_connections = try(local.combined_objects_vpn_gateway_connections, null)
139+
vpn_gateway_nat_rules = try(local.combined_objects_vpn_gateway_nat_rules, null)
139140
vpn_sites = try(local.combined_objects_vpn_sites, null)
140141
web_pubsubs = try(local.combined_objects_web_pubsubs, null)
141142
web_pubsub_hubs = try(local.combined_objects_web_pubsub_hubs, null)

locals.combined_objects.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ locals {
172172
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, {}))
173173
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, {}))
174174
combined_objects_vpn_gateway_connections = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_gateway_connections }), try(var.remote_objects.vpn_gateway_connections, {}))
175+
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, {}))
175176
combined_objects_vpn_sites = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_sites }), try(var.remote_objects.vpn_sites, {}))
176177
combined_objects_web_pubsub_hubs = merge(tomap({ (local.client_config.landingzone_key) = module.web_pubsub_hubs }), try(var.remote_objects.web_pubsub_hubs, {}))
177178
combined_objects_web_pubsubs = merge(tomap({ (local.client_config.landingzone_key) = module.web_pubsubs }), try(var.remote_objects.web_pubsubs, {}))

locals.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ locals {
342342
vnet_peerings_v1 = try(var.networking.vnet_peerings_v1, {})
343343
vnets = try(var.networking.vnets, {})
344344
vpn_gateway_connections = try(var.networking.vpn_gateway_connections, {})
345+
vpn_gateway_nat_rules = try(var.networking.vpn_gateway_nat_rules, {})
345346
vpn_sites = try(var.networking.vpn_sites, {})
346347
}
347348

modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ resource "azurerm_vpn_gateway" "s2s_gateway" {
2222
tags = local.tags
2323
virtual_hub_id = azurerm_virtual_hub.vwan_hub.id
2424

25-
scale_unit = var.virtual_hub_config.s2s_config.scale_unit
26-
routing_preference = try(var.virtual_hub_config.s2s_config.routing_preference, "Microsoft Network")
25+
scale_unit = var.virtual_hub_config.s2s_config.scale_unit
26+
routing_preference = try(var.virtual_hub_config.s2s_config.routing_preference, "Microsoft Network")
27+
bgp_route_translation_for_nat_enabled = try(var.virtual_hub_config.s2s_config.bgp_route_translation_for_nat_enabled, false)
2728

2829
dynamic "bgp_settings" {
2930
for_each = try(var.virtual_hub_config.s2s_config.bgp_settings, null) == null ? [] : [1]
@@ -55,4 +56,4 @@ resource "azurerm_vpn_gateway" "s2s_gateway" {
5556
create = "120m"
5657
delete = "120m"
5758
}
58-
}
59+
}

modules/networking/vpn_gateway_connection/module.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ resource "azurerm_vpn_gateway_connection" "vpn_gateway_connection" {
3030
shared_key = try(vpn_link.value.shared_key, null)
3131
local_azure_ip_address_enabled = try(vpn_link.value.local_azure_ip_address_enabled, null)
3232
policy_based_traffic_selector_enabled = try(vpn_link.value.policy_based_traffic_selector_enabled, null)
33+
egress_nat_rule_ids = try(compact(
34+
[
35+
for key, value in vpn_link.value.egress_nat_rules :
36+
can(value.id) ? value.id : var.nat_rules[try(value.lz_key, var.client_config.landingzone_key)][value.key].id
37+
]
38+
), [])
39+
ingress_nat_rule_ids = try(compact(
40+
[
41+
for key, value in vpn_link.value.ingress_nat_rules :
42+
can(value.id) ? value.id : var.nat_rules[try(value.lz_key, var.client_config.landingzone_key)][value.key].id
43+
]
44+
), [])
3345

3446
vpn_site_link_id = coalesce(
3547
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),

modules/networking/vpn_gateway_connection/variables.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ variable "vpn_gateway_id" {}
66
variable "vpn_sites" {}
77
variable "client_config" {}
88
variable "route_tables" {}
9+
variable "nat_rules" {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
terraform {
2+
required_providers {
3+
azurecaf = {
4+
source = "aztfmod/azurecaf"
5+
}
6+
}
7+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
resource "azurerm_vpn_gateway_nat_rule" "vpn_gateway_nat_rule" {
2+
name = var.settings.name
3+
resource_group_name = var.resource_group_name
4+
vpn_gateway_id = var.vpn_gateway_id
5+
ip_configuration_id = try(var.settings.ip_configuration_id, null)
6+
7+
mode = var.settings.mode
8+
type = var.settings.type
9+
10+
dynamic "external_mapping" {
11+
for_each = try(var.settings.external_mapping, {})
12+
13+
content {
14+
address_space = external_mapping.value.address_space
15+
port_range = try(external_mapping.value.port_range, null)
16+
}
17+
}
18+
19+
dynamic "internal_mapping" {
20+
for_each = try(var.settings.internal_mapping, {})
21+
22+
content {
23+
address_space = internal_mapping.value.address_space
24+
port_range = try(internal_mapping.value.port_range, null)
25+
}
26+
}
27+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "id" {
2+
value = azurerm_vpn_gateway_nat_rule.vpn_gateway_nat_rule.id
3+
description = "Resource ID of the VPN Gateway NAT rule"
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
variable "settings" {}
2+
variable "global_settings" {
3+
description = "Global settings object (see module README.md)"
4+
}
5+
variable "vpn_gateway_id" {}
6+
variable "resource_group_name" {
7+
description = "(Required) The name of the resource group where to create the resource."
8+
type = string
9+
}
10+
variable "client_config" {}

0 commit comments

Comments
 (0)