diff --git a/README.md b/README.md index 609e075..7053a94 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ End-to-end testing is not conducted on these modules, as they are individual com - ability to configure multiple vpn gateway connections on sites - site to site vpn capabilities for secure connectivity between networks - point to site vpn support for secure client access to virtual hub +- nat rules support for address translation on vpn gateways ## Requirements @@ -57,6 +58,7 @@ End-to-end testing is not conducted on these modules, as they are individual com | [azurerm_virtual_wan.vwan](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_wan) | resource | | [azurerm_vpn_gateway.vpn_gateway](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/vpn_gateway) | resource | | [azurerm_vpn_gateway_connection.vpn_connection](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/vpn_gateway_connection) | resource | +| [azurerm_vpn_gateway_nat_rule.nat_rule](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/vpn_gateway_nat_rule) | resource | | [azurerm_vpn_server_configuration.p2s_config](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/vpn_server_configuration) | resource | | [azurerm_vpn_site.vpn_site](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/vpn_site) | resource | diff --git a/examples/vpn-site-to-site/README.md b/examples/vpn-site-to-site/README.md index 62561ae..4655443 100644 --- a/examples/vpn-site-to-site/README.md +++ b/examples/vpn-site-to-site/README.md @@ -7,35 +7,52 @@ This deploys a vpn site to site configuration ```hcl vwan = object({ name = string - allow_branch_to_branch_traffic = optional(bool) - disable_vpn_encryption = optional(bool) - vhubs = optional(map(object({ + allow_branch_to_branch_traffic = optional(bool, true) + disable_vpn_encryption = optional(bool, false) + + vhubs = map(object({ location = string - address_prefix = optional(string) + address_prefix = string + site_to_site_vpn = optional(object({ name = string + + nat_rules = optional(map(object({ + external_mappings = map(object({ + address_space = string + port_range = optional(string) + })) + internal_mappings = map(object({ + address_space = string + port_range = optional(string) + })) + }))) + vpn_sites = map(object({ address_prefix = string gateway_ip = string + vpn_links = map(object({ ip_address = string - provider_name = string - speed_in_mbps = number + provider_name = optional(string) + speed_in_mbps = optional(number) })) - connections = optional(map(object({ + + connections = map(object({ shared_key = string connection_type = string - routing_weight = number + routing_weight = optional(number) local_address_ranges = list(string) remote_address_ranges = list(string) + vpn_links = map(object({ shared_key = string - bgp_enabled = bool - protocol = string + bgp_enabled = optional(bool, false) + protocol = optional(string, "IKEv2") })) - }))) + })) })) })) - }))) + })) }) ``` diff --git a/examples/vpn-site-to-site/vhubs.tf b/examples/vpn-site-to-site/vhubs.tf index c1d1591..cfbfa58 100644 --- a/examples/vpn-site-to-site/vhubs.tf +++ b/examples/vpn-site-to-site/vhubs.tf @@ -5,6 +5,34 @@ locals { address_prefix = "10.0.0.0/23" site_to_site_vpn = { name = "weu-s2s-gateway" + nat_rules = { + rule1 = { + external_mappings = { + mapping1 = { + address_space = "192.168.21.0/26" + } + } + internal_mappings = { + mapping1 = { + address_space = "10.4.0.0/26" + } + } + } + rule2 = { + external_mappings = { + mapping1 = { + address_space = "192.168.22.0/26" + port_range = "10000-20000" + } + } + internal_mappings = { + mapping1 = { + address_space = "10.5.0.0/26" + port_range = "10000-20000" + } + } + } + } vpn_sites = { site1 = { address_prefix = "192.168.1.0/24" diff --git a/main.tf b/main.tf index 9e9f861..0ca416b 100644 --- a/main.tf +++ b/main.tf @@ -197,6 +197,41 @@ resource "azurerm_vpn_gateway_connection" "vpn_connection" { } } +# vpn gateway nat rules +resource "azurerm_vpn_gateway_nat_rule" "nat_rule" { + for_each = merge(flatten([ + for vhub_key, vhub in lookup(var.vwan, "vhubs", {}) : [ + for rule_key, rule in lookup(lookup(vhub, "site_to_site_vpn", {}), "nat_rules", {}) : { + "${vhub_key}-${rule_key}" = merge(rule, { + vhub_key = vhub_key + rule_key = rule_key + }) + } + ] + ])...) + + name = coalesce(lookup(each.value, "name", null), each.value.rule_key) + vpn_gateway_id = azurerm_vpn_gateway.vpn_gateway[each.value.vhub_key].id + ip_configuration_id = try(each.value.ip_configuration_id, null) + mode = try(each.value.mode, "EgressSnat") + + dynamic "external_mapping" { + for_each = try(each.value.external_mappings, {}) + content { + address_space = external_mapping.value.address_space + port_range = try(external_mapping.value.port_range, null) + } + } + + dynamic "internal_mapping" { + for_each = try(each.value.internal_mappings, {}) + content { + address_space = internal_mapping.value.address_space + port_range = try(internal_mapping.value.port_range, null) + } + } +} + # security partner provider resource "azurerm_virtual_hub_security_partner_provider" "spp" { for_each = {