From 5718f01d3a0b595d573100087a77325a197229a0 Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 10 Feb 2026 11:10:58 +0100 Subject: [PATCH 01/54] feat: first steps config and evolution azure vpn p2d and s2s module Signed-off-by: jcframil --- modules/azure-vpn/.terraform-docs.yml | 48 ++++++++++++++++++ modules/azure-vpn/data.tf | 17 +++++++ modules/azure-vpn/docs/footer.md | 21 ++++++++ modules/azure-vpn/docs/header.md | 9 ++++ modules/azure-vpn/locals.tf | 6 +++ modules/azure-vpn/network.yaml | 33 ++++++++++++ modules/azure-vpn/p2s.tf | 0 modules/azure-vpn/s2s.tf | 0 modules/azure-vpn/variables.tf | 72 +++++++++++++++++++++++++++ modules/azure-vpn/versions.tf | 10 ++++ modules/azure-vpn/vpn.tf | 36 ++++++++++++++ 11 files changed, 252 insertions(+) create mode 100644 modules/azure-vpn/.terraform-docs.yml create mode 100644 modules/azure-vpn/data.tf create mode 100644 modules/azure-vpn/docs/footer.md create mode 100644 modules/azure-vpn/docs/header.md create mode 100644 modules/azure-vpn/locals.tf create mode 100644 modules/azure-vpn/network.yaml create mode 100644 modules/azure-vpn/p2s.tf create mode 100644 modules/azure-vpn/s2s.tf create mode 100644 modules/azure-vpn/variables.tf create mode 100644 modules/azure-vpn/versions.tf create mode 100644 modules/azure-vpn/vpn.tf diff --git a/modules/azure-vpn/.terraform-docs.yml b/modules/azure-vpn/.terraform-docs.yml new file mode 100644 index 000000000..3a69365ff --- /dev/null +++ b/modules/azure-vpn/.terraform-docs.yml @@ -0,0 +1,48 @@ +formatter: "markdown" + +version: "" + +header-from: docs/header.md +footer-from: docs/footer.md + +recursive: + enabled: false + path: modules + include-main: true + +sections: + hide: [] + show: [] + +content: "" + +output: + file: "README.md" + mode: inject + template: |- + + {{ .Content }} + + +output-values: + enabled: false + from: "" + +sort: + enabled: true + by: name + +settings: + anchor: true + color: true + default: true + description: false + escape: true + hide-empty: false + html: true + indent: 2 + lockfile: true + read-comments: true + required: true + sensitive: true + type: true diff --git a/modules/azure-vpn/data.tf b/modules/azure-vpn/data.tf new file mode 100644 index 000000000..ffcd0548c --- /dev/null +++ b/modules/azure-vpn/data.tf @@ -0,0 +1,17 @@ +## DATA SOURCES SECTION + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network +data "azurerm_resource_group" "this" { + name = var.resource_group_name +} + +data "azurerm_subnet" "this" { + name = var.vpn.subnet.subnet_gw_name + virtual_network_name = var.vpn.subnet.vnet_name + resource_group_name = var.vpn.subnet.resource_group_name +} + +data "azurerm_public_ip" "this" { + name = var.vpn.ip.name + resource_group_name = var.vpn.ip.resource_group_name +} diff --git a/modules/azure-vpn/docs/footer.md b/modules/azure-vpn/docs/footer.md new file mode 100644 index 000000000..d80c961a5 --- /dev/null +++ b/modules/azure-vpn/docs/footer.md @@ -0,0 +1,21 @@ + + +## Examples + +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples): + +- [with_nic](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples/with_nic) - Example using Azure Key Vault for admin password and custom network interface configuration. +- [with_custom_data](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples/with_custom_data) - Example provisioning a VM with custom PowerShell data. +- [with_vault_admin_pass](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples/with_vault_admin_pass) - Example using Key Vault to securely provide the VM admin password. +- You can also use the module to attach additional unmanaged data disks to your VM (see documentation for details). + +## Remote resources + +- **Azure Windows Virtual Machine**: [azurerm_windows_virtual_machine documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) +- **Azure Network Interface**: [azurerm_network_interface documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) +- **Azure Key Vault**: [azurerm_key_vault documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) +- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + +## Support + +For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). diff --git a/modules/azure-vpn/docs/header.md b/modules/azure-vpn/docs/header.md new file mode 100644 index 000000000..d0a6367ba --- /dev/null +++ b/modules/azure-vpn/docs/header.md @@ -0,0 +1,9 @@ +# **Azure Virtual Network Gateway Terraform Module** + +## Overview + + +## Key Features + + +## Basic Usage diff --git a/modules/azure-vpn/locals.tf b/modules/azure-vpn/locals.tf new file mode 100644 index 000000000..87520c493 --- /dev/null +++ b/modules/azure-vpn/locals.tf @@ -0,0 +1,6 @@ +## LOCALS SECTION + +locals { + # Handle tags based on whether to use resource group tags or module-defined tags + tags = var.tags_from_rg ? merge(data.azurerm_resource_group.this.tags, var.tags) : var.tags +} diff --git a/modules/azure-vpn/network.yaml b/modules/azure-vpn/network.yaml new file mode 100644 index 000000000..e26abd4c5 --- /dev/null +++ b/modules/azure-vpn/network.yaml @@ -0,0 +1,33 @@ +kind: TFWorkspaceClaim +lifecycle: production +name: central-management-vpn +system: 'system:central' +owner: group:infra-powerusers +version: '1.0' +providers: + terraform: + policy: apply + name: central-management-vpn + tfStateKey: 4a0d6e40-e7d2-4eb3-9739-836e4b47c1a5 + source: inline + values: + resource_group_name: "central-management" + vnet_name: "central-hub-vnet" + subnet_gw_name: "GatewaySubnet" + location: "westeurope" + vpn_ip_name: "central_vpn_public_ip" + vpn_ip_allocation_method: "Static" + vpn_ip_sku: "Standard" + vpn_gw_name: "central_vpn_gw" + vpn_gw_type: "Vpn" + vpn_gw_vpn_type: "RouteBased" + vpn_gw_active_active: false + vpn_gw_enable_bgp: false + vpn_gw_sku: "VpnGw1AZ" + vpn_gw_client_configuration_public_cert_data: "MIIC9DCCAdygAwIBAgIIOkIywkRQ3VowDQYJKoZIhvcNAQELBQAwGDEWMBQGA1UEAxMNQ09SUE1FIFZQTiBDQTAeFw0yNDAyMDUxNDE4MDNaFw0yNzAyMDQxNDE4MDNaMBgxFjAUBgNVBAMTDUNPUlBNRSBWUE4gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrWp+WyZ/4h+tt3w4hn+T9j2K3mCclHq0d3FvMoqy7bCcU3eS1qX3LydGGNmHGCPZ3zH6xKlmAz+1J/1zEMgqkwQjjQ1f2FoKgZtvPBJ2nxXuRPAVWpZiqCD7iJRnmeGBLZQ0UC9c45f31fkOuR1srLC3Ia70nRAAd4WI54Gwyd4AOd4Wtr0tNSFS88u6pLomWZCO6iaQIMVaIl290PgtNpDSUMQdq2k8UB+6YLU88S6N0hZWHvtFwVV5ZnBNgyqENW/zUY0UjGmQwHiEyDfnZXfWmjPyEEw8YSRZQpspgt8XK9ayfDlNrrTzLIbn7WQf+rCXEBrA5t7h8oLF4f+3xAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQUI4SK84FHlZLPsShG0FZAukx71zANBgkqhkiG9w0BAQsFAAOCAQEAkDsa8NeWcXXFs17USRmWyPCG8qpuFKE7EvkCy4IEuR5STucmJJXc6ufKggGcD3qnv3+TBqSHB46JzLk8mIyc8xy0gCSUGhoAr58Zdq8HEiKkBzk4S03rLH92ik5ox3fra/3IrzXAPbrwJLQi5Pde674US5LW5oX3pBgWGU/hloeyXogNHdbz/j4h0RHSc/yZW0NN72XjhprxoErz6/KrjwX7jHirp5nkzLvj+Jd5kqrBHyreoAODV0e0MSTbLnTiMDNwZOFK0o1BSMrdJQkny0jx0xtp6RZgeg4jcAfkczKW30qrSxbxn/BiwSyxcAhK9Lpxqi5yb//41d1O6rlHJw==" + vpn_gw_client_configuration_public_cert_data-2025: "MIIDEzCCAfugAwIBAgIUI8ltF/gR8SZkQEIxDfcw2UfKpWEwDQYJKoZIhvcNAQEL BQAwGTEXMBUGA1UEAwwOQ0VOVFJBTCBWUE4gQ0EwHhcNMjUxMDE1MDkzMTI1WhcN MjcxMDE1MDkzMTI1WjAZMRcwFQYDVQQDDA5DRU5UUkFMIFZQTiBDQTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAN481Yap0G0DGInaReEKqMDiFSBPSj9u bEGrIrq+V1/WCVC+eRR32sC+MwAWU/xP3jMazf61PZNduRktmbdqvbc6jFeurD+y lOdo0NFI7sxesWQAdrFVitKmWMbDWanlzACYzSP8ThuHh39cY4i/9UO0nDr1Bg86 hj4kULqJzvb4W4mYAzqVPvRojBPkoI7/xHlFFihk7uie/+DaXWm3vazTrA6HaHnR SsKc2DBZnvpIP1H8AUTOP4cERXp+3RN8dWSHk2LvYnI4yZOOqqyjOG2MwbSWeY9d wuZUdmDkt3WYy58iwvuhOZ2psrfNKZ+h5nww0ga2Pubqv0vehTtWjCECAwEAAaNT MFEwHQYDVR0OBBYEFNH1/rCIXAGVOVmsNlA8SrypmfBKMB8GA1UdIwQYMBaAFNH1 /rCIXAGVOVmsNlA8SrypmfBKMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL BQADggEBADz0cZXuhpDktSC0jjLzKYCwzJgRvXUr9EphiAbqEGQwZ8iiPWH7YMRR HYEWuBX1FygMRyB4nMTuwUbSG5vMGjHMqWuPGz8IZhiMKez0fnn8QqE6Cc55Tg5K YpPYoEzSmvvSkC0lkZI1nOkYvYxmEmjP3T76BLqsFOZ91rW453MlAyLB9p/Qcvmu 4CH5p2N0tBKvPSAkm5YxmMcL4TuKfozJoZzqE4V9qCdW+Lz/Y00WK3HRqcRmDNM/ 2RRuj+GtP2yv+LMrQm2cNMTYH7BCpUxlZevCl8YdcLGawILF4VlBeq5d98q6G0qH T2yZaem03m0hGOwfZLrc/c5M9rgD+iE=" + context: + providers: + - name: azure-provider-central + backend: + name: azure-backend-terraform diff --git a/modules/azure-vpn/p2s.tf b/modules/azure-vpn/p2s.tf new file mode 100644 index 000000000..e69de29bb diff --git a/modules/azure-vpn/s2s.tf b/modules/azure-vpn/s2s.tf new file mode 100644 index 000000000..e69de29bb diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf new file mode 100644 index 000000000..a2df24b0d --- /dev/null +++ b/modules/azure-vpn/variables.tf @@ -0,0 +1,72 @@ +## VARIABLES SECTION +variable "resource_group_name" { + type = string +} + +variable "vnet_name" { + type = string +} + +variable "subnet_gw_name" { + type = string +} + +variable "location" { + type = string +} + +variable "vpn_ip_name" { + type = string +} + +variable "vpn_ip_allocation_method" { + type = string +} + +variable "vpn_ip_sku" { + type = string +} + +variable "vpn_gw_name" { + type = string +} + +variable "vpn_gw_type" { + type = string +} + +variable "vpn_gw_vpn_type" { + type = string +} + +variable "vpn_gw_active_active" { + type = bool +} + +variable "vpn_gw_enable_bgp" { + type = bool +} + +variable "vpn_gw_sku" { + type = string +} + +variable "vpn_gw_client_configuration_public_cert_data" { + type = string +} + +variable "vpn_gw_client_configuration_public_cert_data-2025" { + type = string +} + +variable "tags_from_rg" { + description = "Use resource group tags as base for module tags" + type = bool + default = false +} + +variable "tags" { + description = "Tags to apply to resources" + type = map(string) + default = {} +} diff --git a/modules/azure-vpn/versions.tf b/modules/azure-vpn/versions.tf new file mode 100644 index 000000000..64c91805b --- /dev/null +++ b/modules/azure-vpn/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.7.0" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.58.0" + } + } +} diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf new file mode 100644 index 000000000..ddbbd1dca --- /dev/null +++ b/modules/azure-vpn/vpn.tf @@ -0,0 +1,36 @@ +resource "azurerm_virtual_network_gateway" "this" { + name = var.vpn.name + location = var.vpn.location + resource_group_name = var.vpn.resource_group_name + type = var.vpn.type + vpn_type = var.vpn.vpn_type + active_active = var.vpn.active_active + enable_bgp = var.vpn.enable_bgp + sku = var.vpn.sku + tags = local.tags + + ip_configuration { + name = "${var.vpn.ip.name}-ipconfig" + public_ip_address_id = data.azurerm_public_ip.this.id + private_ip_address_allocation = var.vpn.ip.allocation_method + subnet_id = data.azurerm_subnet.this.id + } + + custom_route { + address_prefixes = var.vpn.custom_route.address_prefixes + } + + vpn_client_configuration { + address_space = var.vpn.vpn_client.address_space + aad_audience = var.vpn.vpn_client.aad_audience + aad_issuer = var.vpn.vpn_client.aad_issuer + aad_tenant = var.vpn.vpn_client.aad_tenant + dynamic "root_certificate" { + for_each = var.vpn.vpn_client.public_cert_data != null ? [var.vpn.vpn_client] : [] + content { + name = root_certificate.value.root_certificate_name + public_cert_data = root_certificate.value.public_cert_data + } + } + } +} From 2b731693f110a0a202aa9b5e0f68388d07710c35 Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 10 Feb 2026 15:48:56 +0100 Subject: [PATCH 02/54] feat: first steps config and evolution azure vpn p2d and s2s module Signed-off-by: jcframil --- modules/azure-vpn/data.tf | 2 +- modules/azure-vpn/network.yaml | 33 ----------- modules/azure-vpn/p2s.tf | 0 modules/azure-vpn/s2s.tf | 24 ++++++++ modules/azure-vpn/variables.tf | 104 +++++++++++++++------------------ modules/azure-vpn/vpn.tf | 60 +++++++++---------- 6 files changed, 97 insertions(+), 126 deletions(-) delete mode 100644 modules/azure-vpn/network.yaml delete mode 100644 modules/azure-vpn/p2s.tf diff --git a/modules/azure-vpn/data.tf b/modules/azure-vpn/data.tf index ffcd0548c..2c58d36c0 100644 --- a/modules/azure-vpn/data.tf +++ b/modules/azure-vpn/data.tf @@ -2,7 +2,7 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network data "azurerm_resource_group" "this" { - name = var.resource_group_name + name = var.vpn.resource_group_name } data "azurerm_subnet" "this" { diff --git a/modules/azure-vpn/network.yaml b/modules/azure-vpn/network.yaml deleted file mode 100644 index e26abd4c5..000000000 --- a/modules/azure-vpn/network.yaml +++ /dev/null @@ -1,33 +0,0 @@ -kind: TFWorkspaceClaim -lifecycle: production -name: central-management-vpn -system: 'system:central' -owner: group:infra-powerusers -version: '1.0' -providers: - terraform: - policy: apply - name: central-management-vpn - tfStateKey: 4a0d6e40-e7d2-4eb3-9739-836e4b47c1a5 - source: inline - values: - resource_group_name: "central-management" - vnet_name: "central-hub-vnet" - subnet_gw_name: "GatewaySubnet" - location: "westeurope" - vpn_ip_name: "central_vpn_public_ip" - vpn_ip_allocation_method: "Static" - vpn_ip_sku: "Standard" - vpn_gw_name: "central_vpn_gw" - vpn_gw_type: "Vpn" - vpn_gw_vpn_type: "RouteBased" - vpn_gw_active_active: false - vpn_gw_enable_bgp: false - vpn_gw_sku: "VpnGw1AZ" - vpn_gw_client_configuration_public_cert_data: "MIIC9DCCAdygAwIBAgIIOkIywkRQ3VowDQYJKoZIhvcNAQELBQAwGDEWMBQGA1UEAxMNQ09SUE1FIFZQTiBDQTAeFw0yNDAyMDUxNDE4MDNaFw0yNzAyMDQxNDE4MDNaMBgxFjAUBgNVBAMTDUNPUlBNRSBWUE4gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrWp+WyZ/4h+tt3w4hn+T9j2K3mCclHq0d3FvMoqy7bCcU3eS1qX3LydGGNmHGCPZ3zH6xKlmAz+1J/1zEMgqkwQjjQ1f2FoKgZtvPBJ2nxXuRPAVWpZiqCD7iJRnmeGBLZQ0UC9c45f31fkOuR1srLC3Ia70nRAAd4WI54Gwyd4AOd4Wtr0tNSFS88u6pLomWZCO6iaQIMVaIl290PgtNpDSUMQdq2k8UB+6YLU88S6N0hZWHvtFwVV5ZnBNgyqENW/zUY0UjGmQwHiEyDfnZXfWmjPyEEw8YSRZQpspgt8XK9ayfDlNrrTzLIbn7WQf+rCXEBrA5t7h8oLF4f+3xAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQUI4SK84FHlZLPsShG0FZAukx71zANBgkqhkiG9w0BAQsFAAOCAQEAkDsa8NeWcXXFs17USRmWyPCG8qpuFKE7EvkCy4IEuR5STucmJJXc6ufKggGcD3qnv3+TBqSHB46JzLk8mIyc8xy0gCSUGhoAr58Zdq8HEiKkBzk4S03rLH92ik5ox3fra/3IrzXAPbrwJLQi5Pde674US5LW5oX3pBgWGU/hloeyXogNHdbz/j4h0RHSc/yZW0NN72XjhprxoErz6/KrjwX7jHirp5nkzLvj+Jd5kqrBHyreoAODV0e0MSTbLnTiMDNwZOFK0o1BSMrdJQkny0jx0xtp6RZgeg4jcAfkczKW30qrSxbxn/BiwSyxcAhK9Lpxqi5yb//41d1O6rlHJw==" - vpn_gw_client_configuration_public_cert_data-2025: "MIIDEzCCAfugAwIBAgIUI8ltF/gR8SZkQEIxDfcw2UfKpWEwDQYJKoZIhvcNAQEL BQAwGTEXMBUGA1UEAwwOQ0VOVFJBTCBWUE4gQ0EwHhcNMjUxMDE1MDkzMTI1WhcN MjcxMDE1MDkzMTI1WjAZMRcwFQYDVQQDDA5DRU5UUkFMIFZQTiBDQTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAN481Yap0G0DGInaReEKqMDiFSBPSj9u bEGrIrq+V1/WCVC+eRR32sC+MwAWU/xP3jMazf61PZNduRktmbdqvbc6jFeurD+y lOdo0NFI7sxesWQAdrFVitKmWMbDWanlzACYzSP8ThuHh39cY4i/9UO0nDr1Bg86 hj4kULqJzvb4W4mYAzqVPvRojBPkoI7/xHlFFihk7uie/+DaXWm3vazTrA6HaHnR SsKc2DBZnvpIP1H8AUTOP4cERXp+3RN8dWSHk2LvYnI4yZOOqqyjOG2MwbSWeY9d wuZUdmDkt3WYy58iwvuhOZ2psrfNKZ+h5nww0ga2Pubqv0vehTtWjCECAwEAAaNT MFEwHQYDVR0OBBYEFNH1/rCIXAGVOVmsNlA8SrypmfBKMB8GA1UdIwQYMBaAFNH1 /rCIXAGVOVmsNlA8SrypmfBKMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL BQADggEBADz0cZXuhpDktSC0jjLzKYCwzJgRvXUr9EphiAbqEGQwZ8iiPWH7YMRR HYEWuBX1FygMRyB4nMTuwUbSG5vMGjHMqWuPGz8IZhiMKez0fnn8QqE6Cc55Tg5K YpPYoEzSmvvSkC0lkZI1nOkYvYxmEmjP3T76BLqsFOZ91rW453MlAyLB9p/Qcvmu 4CH5p2N0tBKvPSAkm5YxmMcL4TuKfozJoZzqE4V9qCdW+Lz/Y00WK3HRqcRmDNM/ 2RRuj+GtP2yv+LMrQm2cNMTYH7BCpUxlZevCl8YdcLGawILF4VlBeq5d98q6G0qH T2yZaem03m0hGOwfZLrc/c5M9rgD+iE=" - context: - providers: - - name: azure-provider-central - backend: - name: azure-backend-terraform diff --git a/modules/azure-vpn/p2s.tf b/modules/azure-vpn/p2s.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/azure-vpn/s2s.tf b/modules/azure-vpn/s2s.tf index e69de29bb..569c4a4b9 100644 --- a/modules/azure-vpn/s2s.tf +++ b/modules/azure-vpn/s2s.tf @@ -0,0 +1,24 @@ +## S2S VPN SECTION + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway +resource "azurerm_local_network_gateway" "this" { + for_each = { for idx, s in var.s2s : idx => s } + name = each.value.local_gateway_name + location = var.vpn.location + resource_group_name = var.vpn.resource_group_name + gateway_address = each.value.local_gateway_ip + address_space = each.value.local_gateway_address_space +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection +resource "azurerm_virtual_network_gateway_connection" "this" { + for_each = { for idx, s in var.s2s : idx => s } + name = each.value.connection_name + location = var.vpn.location + resource_group_name = var.vpn.resource_group_name + type = var.s2s[0].type + virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id + local_network_gateway_id = azurerm_local_network_gateway.this[each.key].id + shared_key = each.value.shared_key + enable_bgp = each.value.enable_bgp +} diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index a2df24b0d..b50c5c451 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -1,62 +1,50 @@ ## VARIABLES SECTION -variable "resource_group_name" { - type = string -} - -variable "vnet_name" { - type = string -} - -variable "subnet_gw_name" { - type = string -} - -variable "location" { - type = string -} - -variable "vpn_ip_name" { - type = string -} - -variable "vpn_ip_allocation_method" { - type = string -} - -variable "vpn_ip_sku" { - type = string -} - -variable "vpn_gw_name" { - type = string -} - -variable "vpn_gw_type" { - type = string -} - -variable "vpn_gw_vpn_type" { - type = string -} - -variable "vpn_gw_active_active" { - type = bool -} - -variable "vpn_gw_enable_bgp" { - type = bool -} - -variable "vpn_gw_sku" { - type = string -} - -variable "vpn_gw_client_configuration_public_cert_data" { - type = string -} - -variable "vpn_gw_client_configuration_public_cert_data-2025" { - type = string +variable "vpn" { + description = "VPN Gateway configuration object (includes P2S config)" + type = object({ + location = string + resource_group_name = string + gateway_name = string + ip_name = string + public_ip_id = string + ip_allocation_method = string + gateway_subnet_id = string + type = string + vpn_type = string + active_active = bool + enable_bgp = bool + sku = string + custom_route_address_prefixes = list(string) + vpn_client_address_space = list(string) + vpn_client_protocols = list(string) + vpn_client_aad_audience = string + vpn_client_aad_issuer = string + vpn_client_aad_tenant = string + root_certificates = list(object({ + name = string + public_cert = string + })) + connection_name = string + vpn_client_address_pool = list(string) + }) +} + +variable "s2s" { + description = "List of Site-to-Site VPN connection objects" + type = list(object({ + type = string + gateway_name = string + gateway_sku = string + ip_name = string + gateway_subnet_id = string + public_ip_id = string + enable_bgp = bool + local_gateway_name = string + local_gateway_ip = string + local_gateway_address_space = list(string) + connection_name = string + shared_key = string + })) } variable "tags_from_rg" { diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index ddbbd1dca..5ad69267c 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -1,36 +1,28 @@ -resource "azurerm_virtual_network_gateway" "this" { - name = var.vpn.name - location = var.vpn.location - resource_group_name = var.vpn.resource_group_name - type = var.vpn.type - vpn_type = var.vpn.vpn_type - active_active = var.vpn.active_active - enable_bgp = var.vpn.enable_bgp - sku = var.vpn.sku - tags = local.tags - - ip_configuration { - name = "${var.vpn.ip.name}-ipconfig" - public_ip_address_id = data.azurerm_public_ip.this.id - private_ip_address_allocation = var.vpn.ip.allocation_method - subnet_id = data.azurerm_subnet.this.id - } +## VPN SECTION - custom_route { - address_prefixes = var.vpn.custom_route.address_prefixes - } - - vpn_client_configuration { - address_space = var.vpn.vpn_client.address_space - aad_audience = var.vpn.vpn_client.aad_audience - aad_issuer = var.vpn.vpn_client.aad_issuer - aad_tenant = var.vpn.vpn_client.aad_tenant - dynamic "root_certificate" { - for_each = var.vpn.vpn_client.public_cert_data != null ? [var.vpn.vpn_client] : [] - content { - name = root_certificate.value.root_certificate_name - public_cert_data = root_certificate.value.public_cert_data - } - } - } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway +resource "azurerm_virtual_network_gateway" "this" { + name = var.vpn.gateway_name + location = var.vpn.location + resource_group_name = var.vpn.resource_group_name + type = var.vpn.type + vpn_type = var.vpn.vpn_type + sku = var.vpn.sku + ip_configuration { + name = var.vpn.ip_name + subnet_id = var.vpn.gateway_subnet_id + public_ip_address_id = var.vpn.public_ip_id + } + enable_bgp = false + vpn_client_configuration { + address_space = var.vpn.vpn_client_address_space + vpn_client_protocols = var.vpn.vpn_client_protocols + dynamic "root_certificate" { + for_each = var.vpn.root_certificates + content { + name = root_certificate.value.name + public_cert_data = root_certificate.value.public_cert_data + } + } + } } From 20c87116d9036666b852f2256a08fd46b1f09af4 Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 09:32:10 +0100 Subject: [PATCH 03/54] fix: add default values to variables Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index b50c5c451..9de95b49b 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -27,6 +27,7 @@ variable "vpn" { connection_name = string vpn_client_address_pool = list(string) }) + default = {} } variable "s2s" { @@ -45,6 +46,7 @@ variable "s2s" { connection_name = string shared_key = string })) + default = {} } variable "tags_from_rg" { From e67bf750bdb21d50f888cbdc63cc620c6c192d5a Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 09:35:05 +0100 Subject: [PATCH 04/54] fix: add default values to variables Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 9de95b49b..dba43a6d1 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -46,8 +46,8 @@ variable "s2s" { connection_name = string shared_key = string })) - default = {} -} + default = [] + } variable "tags_from_rg" { description = "Use resource group tags as base for module tags" From 050685f7c62d532dc70b1a8ca1a877d24be6e39d Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 09:37:33 +0100 Subject: [PATCH 05/54] fix: add default values to variables Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index dba43a6d1..3bbf3ea90 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -27,7 +27,6 @@ variable "vpn" { connection_name = string vpn_client_address_pool = list(string) }) - default = {} } variable "s2s" { From d7fca059faf6bc1642d341f6bbe7a63e582a40e9 Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 13:16:24 +0100 Subject: [PATCH 06/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/data.tf | 10 +++++----- modules/azure-vpn/variables.tf | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/azure-vpn/data.tf b/modules/azure-vpn/data.tf index 2c58d36c0..fb5bf269e 100644 --- a/modules/azure-vpn/data.tf +++ b/modules/azure-vpn/data.tf @@ -6,12 +6,12 @@ data "azurerm_resource_group" "this" { } data "azurerm_subnet" "this" { - name = var.vpn.subnet.subnet_gw_name - virtual_network_name = var.vpn.subnet.vnet_name - resource_group_name = var.vpn.subnet.resource_group_name + name = var.vpn.gateway_subnet_name + virtual_network_name = var.vpn.vnet_name + resource_group_name = var.vpn.resource_group_name } data "azurerm_public_ip" "this" { - name = var.vpn.ip.name - resource_group_name = var.vpn.ip.resource_group_name + name = var.vpn.ip_name + resource_group_name = var.vpn.resource_group_name } diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 3bbf3ea90..b648aea7a 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -2,6 +2,8 @@ variable "vpn" { description = "VPN Gateway configuration object (includes P2S config)" type = object({ + vnet_name = string + gateway_subnet_name = string location = string resource_group_name = string gateway_name = string From c82cdf298a8faf8d4e0beae99a32985453b73d7e Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 13:19:19 +0100 Subject: [PATCH 07/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index b648aea7a..93500add5 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -23,8 +23,8 @@ variable "vpn" { vpn_client_aad_issuer = string vpn_client_aad_tenant = string root_certificates = list(object({ - name = string - public_cert = string + name = string + public_cert_data = string })) connection_name = string vpn_client_address_pool = list(string) From 6a4702144ec74a8a624489402984c0386ea79f3b Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 13:54:52 +0100 Subject: [PATCH 08/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 5 +++-- modules/azure-vpn/vpn.tf | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 93500add5..d926ff8e8 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -23,8 +23,9 @@ variable "vpn" { vpn_client_aad_issuer = string vpn_client_aad_tenant = string root_certificates = list(object({ - name = string - public_cert_data = string + name = string + public_cert = optional(string) + public_cert_data = optional(string) })) connection_name = string vpn_client_address_pool = list(string) diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index 5ad69267c..6251d59dd 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -21,7 +21,10 @@ resource "azurerm_virtual_network_gateway" "this" { for_each = var.vpn.root_certificates content { name = root_certificate.value.name - public_cert_data = root_certificate.value.public_cert_data + public_cert_data = coalesce( + try(root_certificate.value.public_cert_data, null), + try(root_certificate.value.public_cert, null) + ) } } } From 1595cc28d06c67d8b127858283994a67aa37e0ec Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 24 Feb 2026 14:04:42 +0100 Subject: [PATCH 09/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/vpn.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index 6251d59dd..ee2ad9079 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -10,8 +10,8 @@ resource "azurerm_virtual_network_gateway" "this" { sku = var.vpn.sku ip_configuration { name = var.vpn.ip_name - subnet_id = var.vpn.gateway_subnet_id - public_ip_address_id = var.vpn.public_ip_id + subnet_id = data.azurerm_subnet.this.id + public_ip_address_id = data.azurerm_public_ip.this.id } enable_bgp = false vpn_client_configuration { From 273accd399c773f431b601ba9db066f2c05bdcc6 Mon Sep 17 00:00:00 2001 From: jcframil Date: Wed, 25 Feb 2026 08:34:40 +0100 Subject: [PATCH 10/54] fix: change variables Signed-off-by: jcframil --- modules/azure-backup-vault/variables.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/azure-backup-vault/variables.tf b/modules/azure-backup-vault/variables.tf index 711d2fc9e..d5a1a0dac 100644 --- a/modules/azure-backup-vault/variables.tf +++ b/modules/azure-backup-vault/variables.tf @@ -50,7 +50,7 @@ variable "disk_policies" { criteria = object({ absolute_criteria = optional(string) }) - }))) + })), []) })) default = [] } @@ -90,7 +90,7 @@ variable "blob_policies" { data_store_type = string duration = string }) - }))) + })), []) })) default = [] } @@ -135,7 +135,7 @@ variable "postgresql_policies" { weeks_of_month = optional(list(string)) scheduled_backup_times = optional(list(string)) }) - }))) + })), []) })) default = [] } @@ -179,7 +179,7 @@ variable "mysql_policies" { weeks_of_month = optional(list(string)) scheduled_backup_times = optional(list(string)) }) - }))) + })), []) })) default = [] } @@ -223,7 +223,7 @@ variable "kubernetes_policies" { weeks_of_month = optional(list(string)) scheduled_backup_times = optional(list(string)) }) - }))) + })), []) })) default = [] } From be032236610d610baaff82e708d03cad5e3ff0e9 Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 09:11:19 +0100 Subject: [PATCH 11/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index d926ff8e8..3e945bb30 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -8,9 +8,9 @@ variable "vpn" { resource_group_name = string gateway_name = string ip_name = string - public_ip_id = string + public_ip_id = optional(string) ip_allocation_method = string - gateway_subnet_id = string + gateway_subnet_id = optional(string) type = string vpn_type = string active_active = bool From 0a32bf3fa0037db84175cd116dbef746632ec08f Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 09:55:09 +0100 Subject: [PATCH 12/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/vpn.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index ee2ad9079..5bd213ac4 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -8,6 +8,7 @@ resource "azurerm_virtual_network_gateway" "this" { type = var.vpn.type vpn_type = var.vpn.vpn_type sku = var.vpn.sku + tags = local.tags ip_configuration { name = var.vpn.ip_name subnet_id = data.azurerm_subnet.this.id From fa6259dc4f9958cb448abae5c14a19825d26ab10 Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 12:33:19 +0100 Subject: [PATCH 13/54] fix: populate resource vpn with all posible values to extend configuration Signed-off-by: jcframil --- modules/azure-vpn/variables.tf | 79 ++++++++++++++++++++++--------- modules/azure-vpn/vpn.tf | 85 ++++++++++++++++++++++++++++------ 2 files changed, 130 insertions(+), 34 deletions(-) diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 3e945bb30..6eef3e306 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -4,31 +4,68 @@ variable "vpn" { type = object({ vnet_name = string gateway_subnet_name = string - location = string - resource_group_name = string - gateway_name = string - ip_name = string - public_ip_id = optional(string) - ip_allocation_method = string - gateway_subnet_id = optional(string) - type = string - vpn_type = string - active_active = bool - enable_bgp = bool - sku = string - custom_route_address_prefixes = list(string) - vpn_client_address_space = list(string) - vpn_client_protocols = list(string) - vpn_client_aad_audience = string - vpn_client_aad_issuer = string - vpn_client_aad_tenant = string - root_certificates = list(object({ + location = string + resource_group_name = string + gateway_name = string + ip_name = string + public_ip_id = optional(string) + ip_allocation_method = string + gateway_subnet_id = optional(string) + type = string + vpn_type = string + active_active = bool + enable_bgp = bool + sku = string + generation = optional(string) + default_local_network_gateway_id = optional(string) + edge_zone = optional(string) + private_ip_address_enabled = optional(bool) + bgp_route_translation_for_nat_enabled = optional(bool) + dns_forwarding_enabled = optional(bool) + ip_sec_replay_protection_enabled = optional(bool) + remote_vnet_traffic_enabled = optional(bool) + virtual_wan_traffic_enabled = optional(bool) + + # ip_configuration block fields + private_ip_address_allocation = optional(string) + + # custom_route block + custom_route_address_prefixes = optional(list(string), []) + + # vpn_client_configuration block + vpn_client_address_space = optional(list(string), []) + vpn_client_protocols = optional(list(string), []) + vpn_client_aad_tenant = optional(string) + vpn_client_aad_audience = optional(string) + vpn_client_aad_issuer = optional(string) + root_certificates = optional(list(object({ name = string public_cert = optional(string) public_cert_data = optional(string) + })), []) + revoked_certificates = optional(list(object({ + name = string + thumbprint = string + })), []) + vpn_auth_types = optional(list(string), []) + + # bgp_settings block + bgp_settings = optional(object({ + asn = optional(number) + peer_weight = optional(number) + peering_addresses = optional(list(object({ + ip_configuration_name = optional(string) + apipa_addresses = optional(list(string)) + })), []) + })) + + # timeouts block + timeouts = optional(object({ + create = optional(string) + read = optional(string) + update = optional(string) + delete = optional(string) })) - connection_name = string - vpn_client_address_pool = list(string) }) } diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index 5bd213ac4..3fd3bfd4e 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -8,25 +8,84 @@ resource "azurerm_virtual_network_gateway" "this" { type = var.vpn.type vpn_type = var.vpn.vpn_type sku = var.vpn.sku - tags = local.tags + tags = local.tags + active_active = var.vpn.active_active + enable_bgp = var.vpn.enable_bgp + generation = var.vpn.generation + default_local_network_gateway_id = var.vpn.default_local_network_gateway_id + edge_zone = var.vpn.edge_zone + private_ip_address_enabled = var.vpn.private_ip_address_enabled + bgp_route_translation_for_nat_enabled = var.vpn.bgp_route_translation_for_nat_enabled + dns_forwarding_enabled = var.vpn.dns_forwarding_enabled + ip_sec_replay_protection_enabled = var.vpn.ip_sec_replay_protection_enabled + remote_vnet_traffic_enabled = var.vpn.remote_vnet_traffic_enabled + virtual_wan_traffic_enabled = var.vpn.virtual_wan_traffic_enabled + ip_configuration { name = var.vpn.ip_name subnet_id = data.azurerm_subnet.this.id public_ip_address_id = data.azurerm_public_ip.this.id + private_ip_address_allocation = var.vpn.private_ip_address_allocation } - enable_bgp = false - vpn_client_configuration { - address_space = var.vpn.vpn_client_address_space - vpn_client_protocols = var.vpn.vpn_client_protocols - dynamic "root_certificate" { - for_each = var.vpn.root_certificates + + dynamic "custom_route" { + for_each = length(var.vpn.custom_route_address_prefixes) > 0 ? [1] : [] content { - name = root_certificate.value.name - public_cert_data = coalesce( - try(root_certificate.value.public_cert_data, null), - try(root_certificate.value.public_cert, null) - ) + address_prefixes = var.vpn.custom_route_address_prefixes + } + } + + dynamic "vpn_client_configuration" { + for_each = length(var.vpn.vpn_client_address_space) > 0 ? [1] : [] + content { + address_space = var.vpn.vpn_client_address_space + vpn_client_protocols = var.vpn.vpn_client_protocols + aad_tenant = var.vpn.vpn_client_aad_tenant + aad_audience = var.vpn.vpn_client_aad_audience + aad_issuer = var.vpn.vpn_client_aad_issuer + dynamic "root_certificate" { + for_each = var.vpn.root_certificates + content { + name = root_certificate.value.name + public_cert_data = coalesce( + root_certificate.value.public_cert_data, + root_certificate.value.public_cert + ) + } + } + dynamic "revoked_certificate" { + for_each = var.vpn.revoked_certificates + content { + name = revoked_certificate.value.name + thumbprint = revoked_certificate.value.thumbprint + } + } + vpn_auth_types = var.vpn.vpn_auth_types + } + } + + dynamic "bgp_settings" { + for_each = var.vpn.bgp_settings != null ? [1] : [] + content { + asn = var.vpn.bgp_settings.asn + peer_weight = var.vpn.bgp_settings.peer_weight + dynamic "peering_addresses" { + for_each = try(var.vpn.bgp_settings.peering_addresses, []) + content { + ip_configuration_name = peering_addresses.value.ip_configuration_name + apipa_addresses = peering_addresses.value.apipa_addresses + } + } + } + } + + dynamic "timeouts" { + for_each = var.vpn.timeouts != null ? [1] : [] + content { + create = var.vpn.timeouts.create + read = var.vpn.timeouts.read + update = var.vpn.timeouts.update + delete = var.vpn.timeouts.delete } } - } } From 481f0713cad034e0ba07230a82b690e5652efb01 Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 12:55:59 +0100 Subject: [PATCH 14/54] fix: populate resource vpn with all posible values to extend configuration Signed-off-by: jcframil --- modules/azure-vpn/vpn.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index 3fd3bfd4e..7bbe19777 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -29,7 +29,7 @@ resource "azurerm_virtual_network_gateway" "this" { } dynamic "custom_route" { - for_each = length(var.vpn.custom_route_address_prefixes) > 0 ? [1] : [] + for_each = var.vpn.custom_route_address_prefixes != null && length(var.vpn.custom_route_address_prefixes) > 0 ? [1] : [] content { address_prefixes = var.vpn.custom_route_address_prefixes } From 01193c250cc8890f8f7c2fb7ebac123a8c4c3fdf Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 12:58:29 +0100 Subject: [PATCH 15/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/data.tf | 2 +- modules/azure-vpn/variables.tf | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/azure-vpn/data.tf b/modules/azure-vpn/data.tf index fb5bf269e..8c1db8e92 100644 --- a/modules/azure-vpn/data.tf +++ b/modules/azure-vpn/data.tf @@ -12,6 +12,6 @@ data "azurerm_subnet" "this" { } data "azurerm_public_ip" "this" { - name = var.vpn.ip_name + name = var.vpn.public_ip_name resource_group_name = var.vpn.resource_group_name } diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 6eef3e306..2a84b9310 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -8,6 +8,7 @@ variable "vpn" { resource_group_name = string gateway_name = string ip_name = string + public_ip_name = string public_ip_id = optional(string) ip_allocation_method = string gateway_subnet_id = optional(string) From 04b440eaba12c739ccb13bc646c3c31595eae521 Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 13:09:46 +0100 Subject: [PATCH 16/54] fix: change variables Signed-off-by: jcframil --- modules/azure-vpn/vpn.tf | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vpn/vpn.tf index 7bbe19777..7a776e359 100644 --- a/modules/azure-vpn/vpn.tf +++ b/modules/azure-vpn/vpn.tf @@ -28,11 +28,8 @@ resource "azurerm_virtual_network_gateway" "this" { private_ip_address_allocation = var.vpn.private_ip_address_allocation } - dynamic "custom_route" { - for_each = var.vpn.custom_route_address_prefixes != null && length(var.vpn.custom_route_address_prefixes) > 0 ? [1] : [] - content { - address_prefixes = var.vpn.custom_route_address_prefixes - } + custom_route { + address_prefixes = var.vpn.custom_route_address_prefixes } dynamic "vpn_client_configuration" { From 75dccd9ed77a35d032084ecc61aed02ab674ebea Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 14:00:26 +0100 Subject: [PATCH 17/54] fix: add s2s Signed-off-by: jcframil --- modules/azure-vpn/s2s.tf | 33 ++++++++++++++++++++++++++++-- modules/azure-vpn/variables.tf | 34 ++++++++++++++++++++++++++----- modules/azure-vpn/vpn_nat_rule.tf | 19 +++++++++++++++++ 3 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 modules/azure-vpn/vpn_nat_rule.tf diff --git a/modules/azure-vpn/s2s.tf b/modules/azure-vpn/s2s.tf index 569c4a4b9..0c77139a7 100644 --- a/modules/azure-vpn/s2s.tf +++ b/modules/azure-vpn/s2s.tf @@ -16,9 +16,38 @@ resource "azurerm_virtual_network_gateway_connection" "this" { name = each.value.connection_name location = var.vpn.location resource_group_name = var.vpn.resource_group_name - type = var.s2s[0].type + type = each.value.type virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id local_network_gateway_id = azurerm_local_network_gateway.this[each.key].id - shared_key = each.value.shared_key + shared_key = coalesce( + try(each.value.shared_key, null), + try(data.azurerm_key_vault_secret.s2s[each.key].value, null) + ) enable_bgp = each.value.enable_bgp + + dynamic "ipsec_policy" { + for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] + content { + dh_group = ipsec_policy.value.dh_group + ike_encryption = ipsec_policy.value.ike_encryption + ike_integrity = ipsec_policy.value.ike_integrity + ipsec_encryption = ipsec_policy.value.ipsec_encryption + ipsec_integrity = ipsec_policy.value.ipsec_integrity + pfs_group = ipsec_policy.value.pfs_group + sa_lifetime = ipsec_policy.value.sa_lifetime + } + } +} + +# Optionally fetch shared_key from Key Vault if secret_name and vault info are provided +data "azurerm_key_vault_secret" "s2s" { + for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_secret_name + key_vault_id = data.azurerm_key_vault.s2s[each.key].id +} + +data "azurerm_key_vault" "s2s" { + for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_vault_name + resource_group_name = each.value.keyvault_vault_rg } diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 2a84b9310..9b6ea5aca 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -1,3 +1,15 @@ +variable "nat_rules" { + description = "List of NAT rules for the VPN gateway" + type = list(object({ + name = string + mode = string + type = string + ip_configuration_id = string + external_mapping_address_space = string + internal_mapping_address_space = string + })) + default = [] +} ## VARIABLES SECTION variable "vpn" { description = "VPN Gateway configuration object (includes P2S config)" @@ -77,17 +89,29 @@ variable "s2s" { gateway_name = string gateway_sku = string ip_name = string - gateway_subnet_id = string - public_ip_id = string enable_bgp = bool local_gateway_name = string local_gateway_ip = string local_gateway_address_space = list(string) connection_name = string - shared_key = string + shared_key = optional(string) + # Optional: fetch shared_key from Key Vault + keyvault_secret_name = optional(string) + keyvault_vault_name = optional(string) + keyvault_vault_rg = optional(string) + # Optional: advanced IPsec policy + ipsec_policy = optional(object({ + dh_group = string + ike_encryption = string + ike_integrity = string + ipsec_encryption = string + ipsec_integrity = string + pfs_group = string + sa_lifetime = number + })) })) - default = [] - } + default = [] +} variable "tags_from_rg" { description = "Use resource group tags as base for module tags" diff --git a/modules/azure-vpn/vpn_nat_rule.tf b/modules/azure-vpn/vpn_nat_rule.tf new file mode 100644 index 000000000..2dcbe10fd --- /dev/null +++ b/modules/azure-vpn/vpn_nat_rule.tf @@ -0,0 +1,19 @@ +## VPN NAT RULE SECTION + +resource "azurerm_virtual_network_gateway_nat_rule" "this" { + for_each = { for idx, rule in var.nat_rules : idx => rule } + name = each.value.name + resource_group_name = var.vpn.resource_group_name + virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id + mode = each.value.mode + type = each.value.type + ip_configuration_id = each.value.ip_configuration_id + + external_mapping { + address_space = each.value.external_mapping_address_space + } + + internal_mapping { + address_space = each.value.internal_mapping_address_space + } +} From 518a235260d4e24912f27af5411f1f1117a1405d Mon Sep 17 00:00:00 2001 From: jcframil Date: Thu, 26 Feb 2026 14:24:03 +0100 Subject: [PATCH 18/54] fix: separate in two different modules vpn and connections Signed-off-by: jcframil --- modules/azure-vpn-connection/data.tf | 6 ++ modules/azure-vpn-connection/locals.tf | 6 ++ .../s2s.tf | 0 modules/azure-vpn-connection/variables.tf | 65 +++++++++++++++++++ modules/azure-vpn-connection/versions.tf | 10 +++ .../vpn_nat_rule.tf | 0 modules/azure-vpn/variables.tf | 43 ------------ 7 files changed, 87 insertions(+), 43 deletions(-) create mode 100644 modules/azure-vpn-connection/data.tf create mode 100644 modules/azure-vpn-connection/locals.tf rename modules/{azure-vpn => azure-vpn-connection}/s2s.tf (100%) create mode 100644 modules/azure-vpn-connection/variables.tf create mode 100644 modules/azure-vpn-connection/versions.tf rename modules/{azure-vpn => azure-vpn-connection}/vpn_nat_rule.tf (100%) diff --git a/modules/azure-vpn-connection/data.tf b/modules/azure-vpn-connection/data.tf new file mode 100644 index 000000000..b1c310a91 --- /dev/null +++ b/modules/azure-vpn-connection/data.tf @@ -0,0 +1,6 @@ +## DATA SOURCES SECTION + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network +data "azurerm_resource_group" "this" { + name = var.vpn.resource_group_name +} diff --git a/modules/azure-vpn-connection/locals.tf b/modules/azure-vpn-connection/locals.tf new file mode 100644 index 000000000..87520c493 --- /dev/null +++ b/modules/azure-vpn-connection/locals.tf @@ -0,0 +1,6 @@ +## LOCALS SECTION + +locals { + # Handle tags based on whether to use resource group tags or module-defined tags + tags = var.tags_from_rg ? merge(data.azurerm_resource_group.this.tags, var.tags) : var.tags +} diff --git a/modules/azure-vpn/s2s.tf b/modules/azure-vpn-connection/s2s.tf similarity index 100% rename from modules/azure-vpn/s2s.tf rename to modules/azure-vpn-connection/s2s.tf diff --git a/modules/azure-vpn-connection/variables.tf b/modules/azure-vpn-connection/variables.tf new file mode 100644 index 000000000..7b32831b9 --- /dev/null +++ b/modules/azure-vpn-connection/variables.tf @@ -0,0 +1,65 @@ +## VARIABLES SECTION + +variable "vpn" { + description = "VPN Gateway link configuration object variables" + type = object({ + location = string + resource_group_name = string + }) +} + +variable "s2s" { + description = "List of Site-to-Site VPN connection objects" + type = list(object({ + type = string + gateway_name = string + gateway_sku = string + ip_name = string + enable_bgp = bool + local_gateway_name = string + local_gateway_ip = string + local_gateway_address_space = list(string) + connection_name = string + shared_key = optional(string) + # Optional: fetch shared_key from Key Vault + keyvault_secret_name = optional(string) + keyvault_vault_name = optional(string) + keyvault_vault_rg = optional(string) + # Optional: advanced IPsec policy + ipsec_policy = optional(object({ + dh_group = string + ike_encryption = string + ike_integrity = string + ipsec_encryption = string + ipsec_integrity = string + pfs_group = string + sa_lifetime = number + })) + })) + default = [] +} + +variable "nat_rules" { + description = "List of NAT rules for the VPN gateway" + type = list(object({ + name = string + mode = string + type = string + ip_configuration_id = string + external_mapping_address_space = string + internal_mapping_address_space = string + })) + default = [] +} + +variable "tags_from_rg" { + description = "Use resource group tags as base for module tags" + type = bool + default = false +} + +variable "tags" { + description = "Tags to apply to resources" + type = map(string) + default = {} +} diff --git a/modules/azure-vpn-connection/versions.tf b/modules/azure-vpn-connection/versions.tf new file mode 100644 index 000000000..64c91805b --- /dev/null +++ b/modules/azure-vpn-connection/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.7.0" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.58.0" + } + } +} diff --git a/modules/azure-vpn/vpn_nat_rule.tf b/modules/azure-vpn-connection/vpn_nat_rule.tf similarity index 100% rename from modules/azure-vpn/vpn_nat_rule.tf rename to modules/azure-vpn-connection/vpn_nat_rule.tf diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vpn/variables.tf index 9b6ea5aca..64439dde5 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vpn/variables.tf @@ -1,15 +1,3 @@ -variable "nat_rules" { - description = "List of NAT rules for the VPN gateway" - type = list(object({ - name = string - mode = string - type = string - ip_configuration_id = string - external_mapping_address_space = string - internal_mapping_address_space = string - })) - default = [] -} ## VARIABLES SECTION variable "vpn" { description = "VPN Gateway configuration object (includes P2S config)" @@ -82,37 +70,6 @@ variable "vpn" { }) } -variable "s2s" { - description = "List of Site-to-Site VPN connection objects" - type = list(object({ - type = string - gateway_name = string - gateway_sku = string - ip_name = string - enable_bgp = bool - local_gateway_name = string - local_gateway_ip = string - local_gateway_address_space = list(string) - connection_name = string - shared_key = optional(string) - # Optional: fetch shared_key from Key Vault - keyvault_secret_name = optional(string) - keyvault_vault_name = optional(string) - keyvault_vault_rg = optional(string) - # Optional: advanced IPsec policy - ipsec_policy = optional(object({ - dh_group = string - ike_encryption = string - ike_integrity = string - ipsec_encryption = string - ipsec_integrity = string - pfs_group = string - sa_lifetime = number - })) - })) - default = [] -} - variable "tags_from_rg" { description = "Use resource group tags as base for module tags" type = bool From d92d5ce26b7ed93475c7185cd8e3885e6a8c2e6a Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 10:56:24 +0100 Subject: [PATCH 19/54] fix: add config vpn-connection Signed-off-by: jcframil --- modules/azure-vpn-connection/data.tf | 18 ++++++++++++++++++ modules/azure-vpn-connection/s2s.tf | 15 +-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/modules/azure-vpn-connection/data.tf b/modules/azure-vpn-connection/data.tf index b1c310a91..3365dd9a1 100644 --- a/modules/azure-vpn-connection/data.tf +++ b/modules/azure-vpn-connection/data.tf @@ -4,3 +4,21 @@ data "azurerm_resource_group" "this" { name = var.vpn.resource_group_name } + +data "azurerm_virtual_network" "this" { + name = var.vpn.vnet_name + resource_group_name = var.vpn.resource_group_name +} + +# Optionally fetch shared_key from Key Vault if secret_name and vault info are provided +data "azurerm_key_vault_secret" "s2s" { + for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_secret_name + key_vault_id = data.azurerm_key_vault.s2s[each.key].id +} + +data "azurerm_key_vault" "s2s" { + for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_vault_name + resource_group_name = each.value.keyvault_vault_rg +} diff --git a/modules/azure-vpn-connection/s2s.tf b/modules/azure-vpn-connection/s2s.tf index 0c77139a7..39929efd1 100644 --- a/modules/azure-vpn-connection/s2s.tf +++ b/modules/azure-vpn-connection/s2s.tf @@ -17,7 +17,7 @@ resource "azurerm_virtual_network_gateway_connection" "this" { location = var.vpn.location resource_group_name = var.vpn.resource_group_name type = each.value.type - virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id + virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this.id local_network_gateway_id = azurerm_local_network_gateway.this[each.key].id shared_key = coalesce( try(each.value.shared_key, null), @@ -38,16 +38,3 @@ resource "azurerm_virtual_network_gateway_connection" "this" { } } } - -# Optionally fetch shared_key from Key Vault if secret_name and vault info are provided -data "azurerm_key_vault_secret" "s2s" { - for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_secret_name - key_vault_id = data.azurerm_key_vault.s2s[each.key].id -} - -data "azurerm_key_vault" "s2s" { - for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_vault_name - resource_group_name = each.value.keyvault_vault_rg -} From 9c682c60f5bd66486d731e048569eee8bab0ca2c Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 11:05:22 +0100 Subject: [PATCH 20/54] fix: add config vpn-connection Signed-off-by: jcframil --- modules/azure-vpn-connection/data.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn-connection/data.tf b/modules/azure-vpn-connection/data.tf index 3365dd9a1..ead86592a 100644 --- a/modules/azure-vpn-connection/data.tf +++ b/modules/azure-vpn-connection/data.tf @@ -5,8 +5,8 @@ data "azurerm_resource_group" "this" { name = var.vpn.resource_group_name } -data "azurerm_virtual_network" "this" { - name = var.vpn.vnet_name +data "azurerm_virtual_network_gateway" "this" { + name = var.vpn.gateway_name resource_group_name = var.vpn.resource_group_name } From 790bb0ead177e8cbe4567202185dc04c478c477e Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 11:06:47 +0100 Subject: [PATCH 21/54] fix: add config vpn-connection Signed-off-by: jcframil --- modules/azure-vpn-connection/variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn-connection/variables.tf b/modules/azure-vpn-connection/variables.tf index 7b32831b9..274e8b98e 100644 --- a/modules/azure-vpn-connection/variables.tf +++ b/modules/azure-vpn-connection/variables.tf @@ -3,8 +3,8 @@ variable "vpn" { description = "VPN Gateway link configuration object variables" type = object({ - location = string - resource_group_name = string + gateway_name = string + resource_group_name = string }) } From d373ea1605b9db0db7f113e0e3d9ab61ffdbf98d Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 11:10:22 +0100 Subject: [PATCH 22/54] fix: add config vpn-connection Signed-off-by: jcframil --- modules/azure-vpn-connection/s2s.tf | 2 +- modules/azure-vpn-connection/variables.tf | 1 + modules/azure-vpn-connection/vpn_nat_rule.tf | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/azure-vpn-connection/s2s.tf b/modules/azure-vpn-connection/s2s.tf index 39929efd1..4676a24b6 100644 --- a/modules/azure-vpn-connection/s2s.tf +++ b/modules/azure-vpn-connection/s2s.tf @@ -4,7 +4,7 @@ resource "azurerm_local_network_gateway" "this" { for_each = { for idx, s in var.s2s : idx => s } name = each.value.local_gateway_name - location = var.vpn.location + location = each.value.location resource_group_name = var.vpn.resource_group_name gateway_address = each.value.local_gateway_ip address_space = each.value.local_gateway_address_space diff --git a/modules/azure-vpn-connection/variables.tf b/modules/azure-vpn-connection/variables.tf index 274e8b98e..1b431ed71 100644 --- a/modules/azure-vpn-connection/variables.tf +++ b/modules/azure-vpn-connection/variables.tf @@ -14,6 +14,7 @@ variable "s2s" { type = string gateway_name = string gateway_sku = string + location = string ip_name = string enable_bgp = bool local_gateway_name = string diff --git a/modules/azure-vpn-connection/vpn_nat_rule.tf b/modules/azure-vpn-connection/vpn_nat_rule.tf index 2dcbe10fd..37e7748b3 100644 --- a/modules/azure-vpn-connection/vpn_nat_rule.tf +++ b/modules/azure-vpn-connection/vpn_nat_rule.tf @@ -4,7 +4,7 @@ resource "azurerm_virtual_network_gateway_nat_rule" "this" { for_each = { for idx, rule in var.nat_rules : idx => rule } name = each.value.name resource_group_name = var.vpn.resource_group_name - virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id + virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type ip_configuration_id = each.value.ip_configuration_id From 66ed4fbb379333d56b9035f70d544e7c307885f6 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 12:41:15 +0100 Subject: [PATCH 23/54] fix: split into 3 different modules Signed-off-by: jcframil --- modules/azure-localnet-gateway/data.tf | 20 +++++++++ modules/azure-localnet-gateway/locals.tf | 12 +++++ modules/azure-localnet-gateway/main.tf | 12 +++++ modules/azure-localnet-gateway/variables.tf | 45 +++++++++++++++++++ .../versions.tf | 0 .../.terraform-docs.yml | 0 .../{azure-vpn => azure-vnet-gateway}/data.tf | 0 .../docs/footer.md | 0 .../docs/header.md | 0 .../locals.tf | 0 .../vpn.tf => azure-vnet-gateway/main.tf} | 0 .../variables.tf | 13 ++++++ modules/azure-vnet-gateway/versions.tf | 10 +++++ .../vpn_nat_rule.tf | 0 modules/azure-vpn-connection/data.tf | 6 +-- .../azure-vpn-connection/{s2s.tf => main.tf} | 21 +++------ modules/azure-vpn-connection/variables.tf | 2 +- 17 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 modules/azure-localnet-gateway/data.tf create mode 100644 modules/azure-localnet-gateway/locals.tf create mode 100644 modules/azure-localnet-gateway/main.tf create mode 100644 modules/azure-localnet-gateway/variables.tf rename modules/{azure-vpn => azure-localnet-gateway}/versions.tf (100%) rename modules/{azure-vpn => azure-vnet-gateway}/.terraform-docs.yml (100%) rename modules/{azure-vpn => azure-vnet-gateway}/data.tf (100%) rename modules/{azure-vpn => azure-vnet-gateway}/docs/footer.md (100%) rename modules/{azure-vpn => azure-vnet-gateway}/docs/header.md (100%) rename modules/{azure-vpn => azure-vnet-gateway}/locals.tf (100%) rename modules/{azure-vpn/vpn.tf => azure-vnet-gateway/main.tf} (100%) rename modules/{azure-vpn => azure-vnet-gateway}/variables.tf (87%) create mode 100644 modules/azure-vnet-gateway/versions.tf rename modules/{azure-vpn-connection => azure-vnet-gateway}/vpn_nat_rule.tf (100%) rename modules/azure-vpn-connection/{s2s.tf => main.tf} (60%) diff --git a/modules/azure-localnet-gateway/data.tf b/modules/azure-localnet-gateway/data.tf new file mode 100644 index 000000000..1a40bc5fd --- /dev/null +++ b/modules/azure-localnet-gateway/data.tf @@ -0,0 +1,20 @@ +## DATA SOURCES SECTION + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network +data "azurerm_resource_group" "this" { + for_each = { for idx, s in var.localnet : idx => s } + name = each.value.resource_group_name +} + +# Optionally fetch shared_key from Key Vault if secret_name and vault info are provided +data "azurerm_key_vault_secret" "s2s" { + for_each = { for idx, s in var.localnet : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_secret_name + key_vault_id = data.azurerm_key_vault.s2s[each.key].id +} + +data "azurerm_key_vault" "s2s" { + for_each = { for idx, s in var.localnet : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_vault_name + resource_group_name = each.value.keyvault_vault_rg +} diff --git a/modules/azure-localnet-gateway/locals.tf b/modules/azure-localnet-gateway/locals.tf new file mode 100644 index 000000000..febe46e99 --- /dev/null +++ b/modules/azure-localnet-gateway/locals.tf @@ -0,0 +1,12 @@ +## LOCALS SECTION + +locals { + # tags por cada localnet (key = idx) + tags = { for idx, s in var.localnet : + idx => ( + var.tags_from_rg + ? merge(lookup(data.azurerm_resource_group.this, idx, null) != null ? data.azurerm_resource_group.this[idx].tags : {}, var.tags) + : var.tags + ) + } +} diff --git a/modules/azure-localnet-gateway/main.tf b/modules/azure-localnet-gateway/main.tf new file mode 100644 index 000000000..d729a12b6 --- /dev/null +++ b/modules/azure-localnet-gateway/main.tf @@ -0,0 +1,12 @@ +## LOCAL NETWORK GATEWAY SECTION + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway +resource "azurerm_local_network_gateway" "this" { + for_each = { for idx, s in var.localnet : idx => s } + name = each.value.local_gateway_name + location = each.value.location + resource_group_name = each.value.resource_group_name + gateway_address = each.value.local_gateway_ip + address_space = each.value.local_gateway_address_space + tags = local.tags[each.key] +} diff --git a/modules/azure-localnet-gateway/variables.tf b/modules/azure-localnet-gateway/variables.tf new file mode 100644 index 000000000..e0120557d --- /dev/null +++ b/modules/azure-localnet-gateway/variables.tf @@ -0,0 +1,45 @@ +## VARIABLES SECTION + +variable "localnet" { + description = "List of Site-to-Site VPN connection objects" + type = list(object({ + type = string + gateway_name = string + gateway_sku = string + location = string + ip_name = string + enable_bgp = bool + local_gateway_name = string + local_gateway_ip = string + local_gateway_address_space = list(string) + connection_name = string + shared_key = optional(string) + # Optional: fetch shared_key from Key Vault + keyvault_secret_name = optional(string) + keyvault_vault_name = optional(string) + keyvault_vault_rg = optional(string) + # Optional: advanced IPsec policy + ipsec_policy = optional(object({ + dh_group = string + ike_encryption = string + ike_integrity = string + ipsec_encryption = string + ipsec_integrity = string + pfs_group = string + sa_lifetime = number + })) + })) + default = [] +} + +variable "tags_from_rg" { + description = "Use resource group tags as base for module tags" + type = bool + default = false +} + +variable "tags" { + description = "Tags to apply to resources" + type = map(string) + default = {} +} diff --git a/modules/azure-vpn/versions.tf b/modules/azure-localnet-gateway/versions.tf similarity index 100% rename from modules/azure-vpn/versions.tf rename to modules/azure-localnet-gateway/versions.tf diff --git a/modules/azure-vpn/.terraform-docs.yml b/modules/azure-vnet-gateway/.terraform-docs.yml similarity index 100% rename from modules/azure-vpn/.terraform-docs.yml rename to modules/azure-vnet-gateway/.terraform-docs.yml diff --git a/modules/azure-vpn/data.tf b/modules/azure-vnet-gateway/data.tf similarity index 100% rename from modules/azure-vpn/data.tf rename to modules/azure-vnet-gateway/data.tf diff --git a/modules/azure-vpn/docs/footer.md b/modules/azure-vnet-gateway/docs/footer.md similarity index 100% rename from modules/azure-vpn/docs/footer.md rename to modules/azure-vnet-gateway/docs/footer.md diff --git a/modules/azure-vpn/docs/header.md b/modules/azure-vnet-gateway/docs/header.md similarity index 100% rename from modules/azure-vpn/docs/header.md rename to modules/azure-vnet-gateway/docs/header.md diff --git a/modules/azure-vpn/locals.tf b/modules/azure-vnet-gateway/locals.tf similarity index 100% rename from modules/azure-vpn/locals.tf rename to modules/azure-vnet-gateway/locals.tf diff --git a/modules/azure-vpn/vpn.tf b/modules/azure-vnet-gateway/main.tf similarity index 100% rename from modules/azure-vpn/vpn.tf rename to modules/azure-vnet-gateway/main.tf diff --git a/modules/azure-vpn/variables.tf b/modules/azure-vnet-gateway/variables.tf similarity index 87% rename from modules/azure-vpn/variables.tf rename to modules/azure-vnet-gateway/variables.tf index 64439dde5..2035bc557 100644 --- a/modules/azure-vpn/variables.tf +++ b/modules/azure-vnet-gateway/variables.tf @@ -70,6 +70,19 @@ variable "vpn" { }) } +variable "nat_rules" { + description = "List of NAT rules for the VPN gateway" + type = list(object({ + name = string + mode = string + type = string + ip_configuration_id = string + external_mapping_address_space = string + internal_mapping_address_space = string + })) + default = [] +} + variable "tags_from_rg" { description = "Use resource group tags as base for module tags" type = bool diff --git a/modules/azure-vnet-gateway/versions.tf b/modules/azure-vnet-gateway/versions.tf new file mode 100644 index 000000000..64c91805b --- /dev/null +++ b/modules/azure-vnet-gateway/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.7.0" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.58.0" + } + } +} diff --git a/modules/azure-vpn-connection/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf similarity index 100% rename from modules/azure-vpn-connection/vpn_nat_rule.tf rename to modules/azure-vnet-gateway/vpn_nat_rule.tf diff --git a/modules/azure-vpn-connection/data.tf b/modules/azure-vpn-connection/data.tf index ead86592a..83a9aa312 100644 --- a/modules/azure-vpn-connection/data.tf +++ b/modules/azure-vpn-connection/data.tf @@ -2,12 +2,12 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network data "azurerm_resource_group" "this" { - name = var.vpn.resource_group_name + name = var.connection.resource_group_name } data "azurerm_virtual_network_gateway" "this" { - name = var.vpn.gateway_name - resource_group_name = var.vpn.resource_group_name + name = var.connection.gateway_name + resource_group_name = var.connection.resource_group_name } # Optionally fetch shared_key from Key Vault if secret_name and vault info are provided diff --git a/modules/azure-vpn-connection/s2s.tf b/modules/azure-vpn-connection/main.tf similarity index 60% rename from modules/azure-vpn-connection/s2s.tf rename to modules/azure-vpn-connection/main.tf index 4676a24b6..a1aaa132e 100644 --- a/modules/azure-vpn-connection/s2s.tf +++ b/modules/azure-vpn-connection/main.tf @@ -1,21 +1,12 @@ -## S2S VPN SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway -resource "azurerm_local_network_gateway" "this" { - for_each = { for idx, s in var.s2s : idx => s } - name = each.value.local_gateway_name - location = each.value.location - resource_group_name = var.vpn.resource_group_name - gateway_address = each.value.local_gateway_ip - address_space = each.value.local_gateway_address_space -} +## VPN CONNECTION SECTION # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection resource "azurerm_virtual_network_gateway_connection" "this" { - for_each = { for idx, s in var.s2s : idx => s } - name = each.value.connection_name - location = var.vpn.location - resource_group_name = var.vpn.resource_group_name + for_each = { for idx, s in var.connection : idx => s } + name = each.value.name + location = each.value.location + resource_group_name = each.value.resource_group_name + tags = local.tags type = each.value.type virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this.id local_network_gateway_id = azurerm_local_network_gateway.this[each.key].id diff --git a/modules/azure-vpn-connection/variables.tf b/modules/azure-vpn-connection/variables.tf index 1b431ed71..40039839a 100644 --- a/modules/azure-vpn-connection/variables.tf +++ b/modules/azure-vpn-connection/variables.tf @@ -8,7 +8,7 @@ variable "vpn" { }) } -variable "s2s" { +variable "connection" { description = "List of Site-to-Site VPN connection objects" type = list(object({ type = string From b2c26e32f6374a4858a9af8d3308a12676f153de Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 12:59:25 +0100 Subject: [PATCH 24/54] fix: split into 3 different modules Signed-off-by: jcframil --- modules/azure-localnet-gateway/variables.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/azure-localnet-gateway/variables.tf b/modules/azure-localnet-gateway/variables.tf index e0120557d..ffa7c0c5f 100644 --- a/modules/azure-localnet-gateway/variables.tf +++ b/modules/azure-localnet-gateway/variables.tf @@ -4,6 +4,7 @@ variable "localnet" { description = "List of Site-to-Site VPN connection objects" type = list(object({ type = string + resource_group_name = string gateway_name = string gateway_sku = string location = string From ada19770514a9ebe85cf53aca75318adacdb2d1a Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 13:11:37 +0100 Subject: [PATCH 25/54] fix: tags linked to instance Signed-off-by: jcframil --- modules/azure-localnet-gateway/locals.tf | 6 +++--- modules/azure-localnet-gateway/variables.tf | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/azure-localnet-gateway/locals.tf b/modules/azure-localnet-gateway/locals.tf index febe46e99..589528ec5 100644 --- a/modules/azure-localnet-gateway/locals.tf +++ b/modules/azure-localnet-gateway/locals.tf @@ -4,9 +4,9 @@ locals { # tags por cada localnet (key = idx) tags = { for idx, s in var.localnet : idx => ( - var.tags_from_rg - ? merge(lookup(data.azurerm_resource_group.this, idx, null) != null ? data.azurerm_resource_group.this[idx].tags : {}, var.tags) - : var.tags + try(s.tags_from_rg, false) + ? merge(lookup(data.azurerm_resource_group.this, idx, null) != null ? data.azurerm_resource_group.this[idx].tags : {}, try(s.tags, {})) + : try(s.tags, {}) ) } } diff --git a/modules/azure-localnet-gateway/variables.tf b/modules/azure-localnet-gateway/variables.tf index ffa7c0c5f..302f44100 100644 --- a/modules/azure-localnet-gateway/variables.tf +++ b/modules/azure-localnet-gateway/variables.tf @@ -29,6 +29,8 @@ variable "localnet" { pfs_group = string sa_lifetime = number })) + tags_from_rg = optional(bool) + tags = optional(map(string)) })) default = [] } From bd0abd01ff027daafc5e7641fc4bb58d02989704 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 13:13:41 +0100 Subject: [PATCH 26/54] fix: tags linked to instance Signed-off-by: jcframil --- modules/azure-localnet-gateway/locals.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure-localnet-gateway/locals.tf b/modules/azure-localnet-gateway/locals.tf index 589528ec5..e0f897db1 100644 --- a/modules/azure-localnet-gateway/locals.tf +++ b/modules/azure-localnet-gateway/locals.tf @@ -4,7 +4,7 @@ locals { # tags por cada localnet (key = idx) tags = { for idx, s in var.localnet : idx => ( - try(s.tags_from_rg, false) + coalesce(s.tags_from_rg, false) ? merge(lookup(data.azurerm_resource_group.this, idx, null) != null ? data.azurerm_resource_group.this[idx].tags : {}, try(s.tags, {})) : try(s.tags, {}) ) From 7c9ff607da882441ea9e952bbcee616d0aa59964 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 14:51:22 +0100 Subject: [PATCH 27/54] fix: tags linked to instance Signed-off-by: jcframil --- modules/azure-localnet-gateway/variables.tf | 12 ------------ .../data.tf | 0 .../locals.tf | 0 .../main.tf | 0 .../variables.tf | 0 .../versions.tf | 0 6 files changed, 12 deletions(-) rename modules/{azure-vpn-connection => azure-vnet-gateway-connection}/data.tf (100%) rename modules/{azure-vpn-connection => azure-vnet-gateway-connection}/locals.tf (100%) rename modules/{azure-vpn-connection => azure-vnet-gateway-connection}/main.tf (100%) rename modules/{azure-vpn-connection => azure-vnet-gateway-connection}/variables.tf (100%) rename modules/{azure-vpn-connection => azure-vnet-gateway-connection}/versions.tf (100%) diff --git a/modules/azure-localnet-gateway/variables.tf b/modules/azure-localnet-gateway/variables.tf index 302f44100..94bec7c9e 100644 --- a/modules/azure-localnet-gateway/variables.tf +++ b/modules/azure-localnet-gateway/variables.tf @@ -34,15 +34,3 @@ variable "localnet" { })) default = [] } - -variable "tags_from_rg" { - description = "Use resource group tags as base for module tags" - type = bool - default = false -} - -variable "tags" { - description = "Tags to apply to resources" - type = map(string) - default = {} -} diff --git a/modules/azure-vpn-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf similarity index 100% rename from modules/azure-vpn-connection/data.tf rename to modules/azure-vnet-gateway-connection/data.tf diff --git a/modules/azure-vpn-connection/locals.tf b/modules/azure-vnet-gateway-connection/locals.tf similarity index 100% rename from modules/azure-vpn-connection/locals.tf rename to modules/azure-vnet-gateway-connection/locals.tf diff --git a/modules/azure-vpn-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf similarity index 100% rename from modules/azure-vpn-connection/main.tf rename to modules/azure-vnet-gateway-connection/main.tf diff --git a/modules/azure-vpn-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf similarity index 100% rename from modules/azure-vpn-connection/variables.tf rename to modules/azure-vnet-gateway-connection/variables.tf diff --git a/modules/azure-vpn-connection/versions.tf b/modules/azure-vnet-gateway-connection/versions.tf similarity index 100% rename from modules/azure-vpn-connection/versions.tf rename to modules/azure-vnet-gateway-connection/versions.tf From f9c5784bfb756bfc2dada7798ec7d145ac408cf5 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 14:53:36 +0100 Subject: [PATCH 28/54] fix: adapt variables Signed-off-by: jcframil --- modules/azure-vnet-gateway/vpn_nat_rule.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf index 37e7748b3..2dcbe10fd 100644 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ b/modules/azure-vnet-gateway/vpn_nat_rule.tf @@ -4,7 +4,7 @@ resource "azurerm_virtual_network_gateway_nat_rule" "this" { for_each = { for idx, rule in var.nat_rules : idx => rule } name = each.value.name resource_group_name = var.vpn.resource_group_name - virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this.id + virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type ip_configuration_id = each.value.ip_configuration_id From 176c93c07fb6ecd9ee080f98cf2845672cf7df3c Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 14:57:35 +0100 Subject: [PATCH 29/54] fix: adapt variables Signed-off-by: jcframil --- modules/azure-vnet-gateway/vpn_nat_rule.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf index 2dcbe10fd..d7bc00bf0 100644 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ b/modules/azure-vnet-gateway/vpn_nat_rule.tf @@ -1,5 +1,6 @@ ## VPN NAT RULE SECTION +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_nat_rule resource "azurerm_virtual_network_gateway_nat_rule" "this" { for_each = { for idx, rule in var.nat_rules : idx => rule } name = each.value.name @@ -7,7 +8,7 @@ resource "azurerm_virtual_network_gateway_nat_rule" "this" { virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type - ip_configuration_id = each.value.ip_configuration_id + ip_configuration_id = azurerm_virtual_network_gateway.this.ip_configuration.id external_mapping { address_space = each.value.external_mapping_address_space From 3937206c5ec8463ba9c4a83f1c5a987ab4d67431 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 15:01:32 +0100 Subject: [PATCH 30/54] fix: adapt variables Signed-off-by: jcframil --- modules/azure-vnet-gateway/vpn_nat_rule.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf index d7bc00bf0..631472a01 100644 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ b/modules/azure-vnet-gateway/vpn_nat_rule.tf @@ -8,7 +8,7 @@ resource "azurerm_virtual_network_gateway_nat_rule" "this" { virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type - ip_configuration_id = azurerm_virtual_network_gateway.this.ip_configuration.id + ip_configuration_id = azurerm_virtual_network_gateway.this.ip_configuration[0].id external_mapping { address_space = each.value.external_mapping_address_space From 0dc8a66753937e0d4954e97137075caf55fc64cf Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 15:10:44 +0100 Subject: [PATCH 31/54] fix: adapt variables Signed-off-by: jcframil --- modules/azure-vnet-gateway/data.tf | 5 +++++ modules/azure-vnet-gateway/vpn_nat_rule.tf | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/azure-vnet-gateway/data.tf b/modules/azure-vnet-gateway/data.tf index 8c1db8e92..2734ae91b 100644 --- a/modules/azure-vnet-gateway/data.tf +++ b/modules/azure-vnet-gateway/data.tf @@ -15,3 +15,8 @@ data "azurerm_public_ip" "this" { name = var.vpn.public_ip_name resource_group_name = var.vpn.resource_group_name } + +data "azurerm_virtual_network_gateway" "this" { + name = var.vpn.gateway_name + resource_group_name = var.vpn.resource_group_name +} diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf index 631472a01..62a07a467 100644 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ b/modules/azure-vnet-gateway/vpn_nat_rule.tf @@ -8,7 +8,7 @@ resource "azurerm_virtual_network_gateway_nat_rule" "this" { virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type - ip_configuration_id = azurerm_virtual_network_gateway.this.ip_configuration[0].id + ip_configuration_id = data.azurerm_virtual_network_gateway.this.ip_configuration[0].id external_mapping { address_space = each.value.external_mapping_address_space From 5046fcafdf06962ce8c4e94f5de55ecb6044d401 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 15:15:49 +0100 Subject: [PATCH 32/54] fix: adapt variables Signed-off-by: jcframil --- modules/azure-vnet-gateway/variables.tf | 2 +- modules/azure-vnet-gateway/vpn_nat_rule.tf | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/azure-vnet-gateway/variables.tf b/modules/azure-vnet-gateway/variables.tf index 2035bc557..1ad6c6251 100644 --- a/modules/azure-vnet-gateway/variables.tf +++ b/modules/azure-vnet-gateway/variables.tf @@ -76,7 +76,7 @@ variable "nat_rules" { name = string mode = string type = string - ip_configuration_id = string + ip_configuration_id = optional(string) external_mapping_address_space = string internal_mapping_address_space = string })) diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf index 62a07a467..37d9e3949 100644 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ b/modules/azure-vnet-gateway/vpn_nat_rule.tf @@ -8,7 +8,10 @@ resource "azurerm_virtual_network_gateway_nat_rule" "this" { virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type - ip_configuration_id = data.azurerm_virtual_network_gateway.this.ip_configuration[0].id + ip_configuration_id = coalesce( + try(each.value.ip_configuration_id, null), + data.azurerm_virtual_network_gateway.this.ip_configuration[0].id + ) external_mapping { address_space = each.value.external_mapping_address_space From 94ffaa64ddbcb3dd5c721ddcf18ce40caf883ce2 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 15:42:25 +0100 Subject: [PATCH 33/54] fix: adapt variables Signed-off-by: jcframil --- modules/azure-localnet-gateway/data.tf | 13 --------- modules/azure-localnet-gateway/variables.tf | 27 +++---------------- modules/azure-vnet-gateway-connection/data.tf | 4 +-- .../azure-vnet-gateway-connection/locals.tf | 10 +++++-- 4 files changed, 13 insertions(+), 41 deletions(-) diff --git a/modules/azure-localnet-gateway/data.tf b/modules/azure-localnet-gateway/data.tf index 1a40bc5fd..6760bcf0e 100644 --- a/modules/azure-localnet-gateway/data.tf +++ b/modules/azure-localnet-gateway/data.tf @@ -5,16 +5,3 @@ data "azurerm_resource_group" "this" { for_each = { for idx, s in var.localnet : idx => s } name = each.value.resource_group_name } - -# Optionally fetch shared_key from Key Vault if secret_name and vault info are provided -data "azurerm_key_vault_secret" "s2s" { - for_each = { for idx, s in var.localnet : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_secret_name - key_vault_id = data.azurerm_key_vault.s2s[each.key].id -} - -data "azurerm_key_vault" "s2s" { - for_each = { for idx, s in var.localnet : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_vault_name - resource_group_name = each.value.keyvault_vault_rg -} diff --git a/modules/azure-localnet-gateway/variables.tf b/modules/azure-localnet-gateway/variables.tf index 94bec7c9e..8bcf9ad16 100644 --- a/modules/azure-localnet-gateway/variables.tf +++ b/modules/azure-localnet-gateway/variables.tf @@ -1,34 +1,13 @@ ## VARIABLES SECTION variable "localnet" { - description = "List of Site-to-Site VPN connection objects" + description = "List of local network gateway objects" type = list(object({ - type = string - resource_group_name = string - gateway_name = string - gateway_sku = string - location = string - ip_name = string - enable_bgp = bool local_gateway_name = string + location = string + resource_group_name = string local_gateway_ip = string local_gateway_address_space = list(string) - connection_name = string - shared_key = optional(string) - # Optional: fetch shared_key from Key Vault - keyvault_secret_name = optional(string) - keyvault_vault_name = optional(string) - keyvault_vault_rg = optional(string) - # Optional: advanced IPsec policy - ipsec_policy = optional(object({ - dh_group = string - ike_encryption = string - ike_integrity = string - ipsec_encryption = string - ipsec_integrity = string - pfs_group = string - sa_lifetime = number - })) tags_from_rg = optional(bool) tags = optional(map(string)) })) diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf index 83a9aa312..d3b96c73e 100644 --- a/modules/azure-vnet-gateway-connection/data.tf +++ b/modules/azure-vnet-gateway-connection/data.tf @@ -12,13 +12,13 @@ data "azurerm_virtual_network_gateway" "this" { # Optionally fetch shared_key from Key Vault if secret_name and vault info are provided data "azurerm_key_vault_secret" "s2s" { - for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } name = each.value.keyvault_secret_name key_vault_id = data.azurerm_key_vault.s2s[each.key].id } data "azurerm_key_vault" "s2s" { - for_each = { for idx, s in var.s2s : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } name = each.value.keyvault_vault_name resource_group_name = each.value.keyvault_vault_rg } diff --git a/modules/azure-vnet-gateway-connection/locals.tf b/modules/azure-vnet-gateway-connection/locals.tf index 87520c493..1cd4a9d77 100644 --- a/modules/azure-vnet-gateway-connection/locals.tf +++ b/modules/azure-vnet-gateway-connection/locals.tf @@ -1,6 +1,12 @@ ## LOCALS SECTION locals { - # Handle tags based on whether to use resource group tags or module-defined tags - tags = var.tags_from_rg ? merge(data.azurerm_resource_group.this.tags, var.tags) : var.tags + # tags por cada localnet (key = idx) + tags = { for idx, s in var.connection : + idx => ( + coalesce(s.tags_from_rg, false) + ? merge(lookup(data.azurerm_resource_group.this, idx, null) != null ? data.azurerm_resource_group.this[idx].tags : {}, try(s.tags, {})) + : try(s.tags, {}) + ) + } } From ed9f1591945be9a3f6c83362535e7549be58855d Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 27 Feb 2026 15:54:03 +0100 Subject: [PATCH 34/54] fix: adapt variables Signed-off-by: jcframil --- .../variables.tf | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 40039839a..8be1dae33 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -40,27 +40,3 @@ variable "connection" { default = [] } -variable "nat_rules" { - description = "List of NAT rules for the VPN gateway" - type = list(object({ - name = string - mode = string - type = string - ip_configuration_id = string - external_mapping_address_space = string - internal_mapping_address_space = string - })) - default = [] -} - -variable "tags_from_rg" { - description = "Use resource group tags as base for module tags" - type = bool - default = false -} - -variable "tags" { - description = "Tags to apply to resources" - type = map(string) - default = {} -} From 11830d90b210c2de883e4f914882d984506c1a2f Mon Sep 17 00:00:00 2001 From: jcframil Date: Tue, 3 Mar 2026 12:28:07 +0100 Subject: [PATCH 35/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 1 + modules/azure-vnet-gateway-connection/variables.tf | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index a1aaa132e..7779afb46 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -26,6 +26,7 @@ resource "azurerm_virtual_network_gateway_connection" "this" { ipsec_integrity = ipsec_policy.value.ipsec_integrity pfs_group = ipsec_policy.value.pfs_group sa_lifetime = ipsec_policy.value.sa_lifetime + sa_datasize = ipsec_policy.value.sa_datasize } } } diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 8be1dae33..3db63bd72 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -35,6 +35,7 @@ variable "connection" { ipsec_integrity = string pfs_group = string sa_lifetime = number + sa_datasize = number })) })) default = [] From f14b46f7e913a61e58205ee91a024d84d4503abf Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 08:44:17 +0100 Subject: [PATCH 36/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/variables.tf | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 3db63bd72..2bea143dc 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -1,13 +1,5 @@ ## VARIABLES SECTION -variable "vpn" { - description = "VPN Gateway link configuration object variables" - type = object({ - gateway_name = string - resource_group_name = string - }) -} - variable "connection" { description = "List of Site-to-Site VPN connection objects" type = list(object({ From 2dd7750e4be66beec26167ee8e3c2a4987db2f9e Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 08:47:38 +0100 Subject: [PATCH 37/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/data.tf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf index d3b96c73e..dc4f2ab08 100644 --- a/modules/azure-vnet-gateway-connection/data.tf +++ b/modules/azure-vnet-gateway-connection/data.tf @@ -1,13 +1,17 @@ ## DATA SOURCES SECTION # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network + +# Iterar sobre cada conexión para los data sources data "azurerm_resource_group" "this" { - name = var.connection.resource_group_name + for_each = { for idx, s in var.connection : idx => s } + name = each.value.resource_group_name } data "azurerm_virtual_network_gateway" "this" { - name = var.connection.gateway_name - resource_group_name = var.connection.resource_group_name + for_each = { for idx, s in var.connection : idx => s } + name = each.value.gateway_name + resource_group_name = each.value.resource_group_name } # Optionally fetch shared_key from Key Vault if secret_name and vault info are provided From aa354ea23ac48a85a2af83dd32ff4cbc595ebd4a Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 09:11:17 +0100 Subject: [PATCH 38/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 4 +-- .../variables.tf | 35 ++++++++++--------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 7779afb46..26c23fa2b 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -8,8 +8,8 @@ resource "azurerm_virtual_network_gateway_connection" "this" { resource_group_name = each.value.resource_group_name tags = local.tags type = each.value.type - virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this.id - local_network_gateway_id = azurerm_local_network_gateway.this[each.key].id + virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this[each.key].id + local_network_gateway_id = var.local_network_gateway_id[each.key] shared_key = coalesce( try(each.value.shared_key, null), try(data.azurerm_key_vault_secret.s2s[each.key].value, null) diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 2bea143dc..816dc7bc6 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -3,22 +3,16 @@ variable "connection" { description = "List of Site-to-Site VPN connection objects" type = list(object({ - type = string - gateway_name = string - gateway_sku = string - location = string - ip_name = string - enable_bgp = bool - local_gateway_name = string - local_gateway_ip = string - local_gateway_address_space = list(string) - connection_name = string - shared_key = optional(string) - # Optional: fetch shared_key from Key Vault - keyvault_secret_name = optional(string) - keyvault_vault_name = optional(string) - keyvault_vault_rg = optional(string) - # Optional: advanced IPsec policy + name = string + location = string + resource_group_name = string + type = string + gateway_name = string + enable_bgp = bool + shared_key = optional(string) + keyvault_secret_name = optional(string) + keyvault_vault_name = optional(string) + keyvault_vault_rg = optional(string) ipsec_policy = optional(object({ dh_group = string ike_encryption = string @@ -28,8 +22,15 @@ variable "connection" { pfs_group = string sa_lifetime = number sa_datasize = number - })) + }) ) + tags_from_rg = optional(bool) + tags = optional(map(string)) })) default = [] } +variable "local_network_gateway_id" { + description = "Map of local network gateway IDs, indexed by connection key" + type = map(string) +} + From 9e8031d730d8d8dd4b04a7d0436085d0cda81e77 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 09:13:38 +0100 Subject: [PATCH 39/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/data.tf | 6 ++++++ modules/azure-vnet-gateway-connection/main.tf | 2 +- modules/azure-vnet-gateway-connection/variables.tf | 4 ---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf index dc4f2ab08..485d99933 100644 --- a/modules/azure-vnet-gateway-connection/data.tf +++ b/modules/azure-vnet-gateway-connection/data.tf @@ -1,3 +1,9 @@ +# Data source para local network gateway +data "azurerm_local_network_gateway" "this" { + for_each = { for idx, s in var.connection : idx => s } + name = each.value.local_gateway_name + resource_group_name = each.value.resource_group_name +} ## DATA SOURCES SECTION # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 26c23fa2b..99af571ba 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -9,7 +9,7 @@ resource "azurerm_virtual_network_gateway_connection" "this" { tags = local.tags type = each.value.type virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this[each.key].id - local_network_gateway_id = var.local_network_gateway_id[each.key] + local_network_gateway_id = data.azurerm_local_network_gateway.this[each.key].id shared_key = coalesce( try(each.value.shared_key, null), try(data.azurerm_key_vault_secret.s2s[each.key].value, null) diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 816dc7bc6..63d3c882c 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -29,8 +29,4 @@ variable "connection" { default = [] } -variable "local_network_gateway_id" { - description = "Map of local network gateway IDs, indexed by connection key" - type = map(string) -} From 0e84d1a591b3629450ea1391f4e68f8eb7d466c6 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 09:20:58 +0100 Subject: [PATCH 40/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/data.tf | 3 +-- modules/azure-vnet-gateway-connection/variables.tf | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf index 485d99933..6c6b7685b 100644 --- a/modules/azure-vnet-gateway-connection/data.tf +++ b/modules/azure-vnet-gateway-connection/data.tf @@ -2,8 +2,7 @@ data "azurerm_local_network_gateway" "this" { for_each = { for idx, s in var.connection : idx => s } name = each.value.local_gateway_name - resource_group_name = each.value.resource_group_name -} + resource_group_name = each.value.local_gateway_resource_group_name ## DATA SOURCES SECTION # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 63d3c882c..5c1e2f6a2 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -6,6 +6,8 @@ variable "connection" { name = string location = string resource_group_name = string + local_gateway_name = string + local_gateway_resource_group_name = string type = string gateway_name = string enable_bgp = bool From f744cf0a94233096bf6bc3efe670a89f1de27e4a Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 09:22:32 +0100 Subject: [PATCH 41/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/data.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf index 6c6b7685b..5dfbc638c 100644 --- a/modules/azure-vnet-gateway-connection/data.tf +++ b/modules/azure-vnet-gateway-connection/data.tf @@ -1,11 +1,11 @@ +## DATA SOURCES SECTION + # Data source para local network gateway data "azurerm_local_network_gateway" "this" { for_each = { for idx, s in var.connection : idx => s } name = each.value.local_gateway_name resource_group_name = each.value.local_gateway_resource_group_name -## DATA SOURCES SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network +} # Iterar sobre cada conexión para los data sources data "azurerm_resource_group" "this" { From a9115f84e192795a99d6567487c80111d3066829 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 09:30:18 +0100 Subject: [PATCH 42/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/locals.tf | 4 ++-- modules/azure-vnet-gateway-connection/main.tf | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/locals.tf b/modules/azure-vnet-gateway-connection/locals.tf index 1cd4a9d77..e257bf436 100644 --- a/modules/azure-vnet-gateway-connection/locals.tf +++ b/modules/azure-vnet-gateway-connection/locals.tf @@ -1,11 +1,11 @@ ## LOCALS SECTION locals { - # tags por cada localnet (key = idx) + # tags por cada connection (key = idx), siempre map(string) tags = { for idx, s in var.connection : idx => ( coalesce(s.tags_from_rg, false) - ? merge(lookup(data.azurerm_resource_group.this, idx, null) != null ? data.azurerm_resource_group.this[idx].tags : {}, try(s.tags, {})) + ? merge(try(data.azurerm_resource_group.this[idx].tags, {}), try(s.tags, {})) : try(s.tags, {}) ) } diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 99af571ba..5329b08a6 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -10,10 +10,11 @@ resource "azurerm_virtual_network_gateway_connection" "this" { type = each.value.type virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this[each.key].id local_network_gateway_id = data.azurerm_local_network_gateway.this[each.key].id - shared_key = coalesce( - try(each.value.shared_key, null), - try(data.azurerm_key_vault_secret.s2s[each.key].value, null) - ) + shared_key = ( + try(each.value.shared_key, null) != null ? each.value.shared_key : ( + try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null + ) + ) enable_bgp = each.value.enable_bgp dynamic "ipsec_policy" { From 3263ab6329a6df5cde664d38b93f0a51a7b7efbb Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 09:32:01 +0100 Subject: [PATCH 43/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 5329b08a6..fce000b99 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -6,7 +6,7 @@ resource "azurerm_virtual_network_gateway_connection" "this" { name = each.value.name location = each.value.location resource_group_name = each.value.resource_group_name - tags = local.tags + tags = local.tags[each.key] type = each.value.type virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this[each.key].id local_network_gateway_id = data.azurerm_local_network_gateway.this[each.key].id From f316eaca50b4a4656c28c3529e6a2f58466421a6 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 10:10:20 +0100 Subject: [PATCH 44/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 46 ++++++++++++------- .../variables.tf | 42 +++++++++++------ 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index fce000b99..0436c451b 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -8,26 +8,40 @@ resource "azurerm_virtual_network_gateway_connection" "this" { resource_group_name = each.value.resource_group_name tags = local.tags[each.key] type = each.value.type - virtual_network_gateway_id = data.azurerm_virtual_network_gateway.this[each.key].id - local_network_gateway_id = data.azurerm_local_network_gateway.this[each.key].id + virtual_network_gateway_id = ( + try(each.value.virtual_network_gateway_id, null) != null ? each.value.virtual_network_gateway_id : data.azurerm_virtual_network_gateway.this[each.key].id + ) + local_network_gateway_id = ( + try(each.value.local_network_gateway_id, null) != null ? each.value.local_network_gateway_id : data.azurerm_local_network_gateway.this[each.key].id + ) shared_key = ( try(each.value.shared_key, null) != null ? each.value.shared_key : ( try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null ) ) - enable_bgp = each.value.enable_bgp + # enable_bgp está deprecado y no debe usarse + enable_bgp = null + connection_protocol = try(each.value.connection_protocol, null) + routing_weight = try(each.value.routing_weight, null) + authorization_key = try(each.value.authorization_key, null) + express_route_circuit_id = try(each.value.express_route_circuit_id, null) + peer_virtual_network_gateway_id = try(each.value.peer_virtual_network_gateway_id, null) + use_policy_based_traffic_selectors = try(each.value.use_policy_based_traffic_selectors, null) + express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) + dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) + connection_mode = try(each.value.connection_mode, null) - dynamic "ipsec_policy" { - for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] - content { - dh_group = ipsec_policy.value.dh_group - ike_encryption = ipsec_policy.value.ike_encryption - ike_integrity = ipsec_policy.value.ike_integrity - ipsec_encryption = ipsec_policy.value.ipsec_encryption - ipsec_integrity = ipsec_policy.value.ipsec_integrity - pfs_group = ipsec_policy.value.pfs_group - sa_lifetime = ipsec_policy.value.sa_lifetime - sa_datasize = ipsec_policy.value.sa_datasize - } - } + dynamic "ipsec_policy" { + for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] + content { + dh_group = ipsec_policy.value.dh_group + ike_encryption = ipsec_policy.value.ike_encryption + ike_integrity = ipsec_policy.value.ike_integrity + ipsec_encryption = ipsec_policy.value.ipsec_encryption + ipsec_integrity = ipsec_policy.value.ipsec_integrity + pfs_group = ipsec_policy.value.pfs_group + sa_lifetime = ipsec_policy.value.sa_lifetime + sa_datasize = ipsec_policy.value.sa_datasize + } + } } diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 5c1e2f6a2..4f996f104 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -3,18 +3,32 @@ variable "connection" { description = "List of Site-to-Site VPN connection objects" type = list(object({ - name = string - location = string - resource_group_name = string - local_gateway_name = string - local_gateway_resource_group_name = string - type = string - gateway_name = string - enable_bgp = bool - shared_key = optional(string) - keyvault_secret_name = optional(string) - keyvault_vault_name = optional(string) - keyvault_vault_rg = optional(string) + name = string + location = string + resource_group_name = string + local_gateway_name = string + local_gateway_resource_group_name = string + type = string + gateway_name = string + # DEPRECATED: enable_bgp is deprecated in azurerm_virtual_network_gateway_connection + enable_bgp = optional(bool) + shared_key = optional(string) + keyvault_secret_name = optional(string) + keyvault_vault_name = optional(string) + keyvault_vault_rg = optional(string) + virtual_network_gateway_id = optional(string) + local_network_gateway_id = optional(string) + connection_protocol = optional(string) + routing_weight = optional(number) + authorization_key = optional(string) + express_route_circuit_id = optional(string) + peer_virtual_network_gateway_id = optional(string) + use_policy_based_traffic_selectors = optional(bool) + express_route_gateway_bypass = optional(bool) + dpd_timeout_seconds = optional(number) + connection_mode = optional(string) + tags_from_rg = optional(bool) + tags = optional(map(string)) ipsec_policy = optional(object({ dh_group = string ike_encryption = string @@ -24,9 +38,7 @@ variable "connection" { pfs_group = string sa_lifetime = number sa_datasize = number - }) ) - tags_from_rg = optional(bool) - tags = optional(map(string)) + })) })) default = [] } From 063cdff5936a3841d7af0861e04289e0177f811f Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 10:17:58 +0100 Subject: [PATCH 45/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/variables.tf | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index 4f996f104..e08e13fca 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -10,8 +10,6 @@ variable "connection" { local_gateway_resource_group_name = string type = string gateway_name = string - # DEPRECATED: enable_bgp is deprecated in azurerm_virtual_network_gateway_connection - enable_bgp = optional(bool) shared_key = optional(string) keyvault_secret_name = optional(string) keyvault_vault_name = optional(string) From d909650ed81a753e89b9376fbb723e7013ba528b Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 10:26:27 +0100 Subject: [PATCH 46/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 3 +++ modules/azure-vnet-gateway-connection/variables.tf | 3 +++ 2 files changed, 6 insertions(+) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 0436c451b..d3f5e4799 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -6,6 +6,9 @@ resource "azurerm_virtual_network_gateway_connection" "this" { name = each.value.name location = each.value.location resource_group_name = each.value.resource_group_name + egress_nat_rule_ids = try(each.value.egress_nat_rule_ids, null) + ingress_nat_rule_ids = try(each.value.ingress_nat_rule_ids, null) + local_azure_ip_address_enabled = try(each.value.local_azure_ip_address_enabled, null) tags = local.tags[each.key] type = each.value.type virtual_network_gateway_id = ( diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index e08e13fca..fbb870542 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -26,6 +26,9 @@ variable "connection" { dpd_timeout_seconds = optional(number) connection_mode = optional(string) tags_from_rg = optional(bool) + egress_nat_rule_ids = optional(list(string)) + ingress_nat_rule_ids = optional(list(string)) + local_azure_ip_address_enabled = optional(bool) tags = optional(map(string)) ipsec_policy = optional(object({ dh_group = string From 1f3d7d58317027065f4d0e93e49ebda70b532da6 Mon Sep 17 00:00:00 2001 From: jcframil Date: Fri, 6 Mar 2026 10:29:46 +0100 Subject: [PATCH 47/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index d3f5e4799..94b323685 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -11,28 +11,27 @@ resource "azurerm_virtual_network_gateway_connection" "this" { local_azure_ip_address_enabled = try(each.value.local_azure_ip_address_enabled, null) tags = local.tags[each.key] type = each.value.type - virtual_network_gateway_id = ( - try(each.value.virtual_network_gateway_id, null) != null ? each.value.virtual_network_gateway_id : data.azurerm_virtual_network_gateway.this[each.key].id - ) - local_network_gateway_id = ( - try(each.value.local_network_gateway_id, null) != null ? each.value.local_network_gateway_id : data.azurerm_local_network_gateway.this[each.key].id - ) - shared_key = ( - try(each.value.shared_key, null) != null ? each.value.shared_key : ( - try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null - ) - ) - # enable_bgp está deprecado y no debe usarse - enable_bgp = null - connection_protocol = try(each.value.connection_protocol, null) - routing_weight = try(each.value.routing_weight, null) - authorization_key = try(each.value.authorization_key, null) - express_route_circuit_id = try(each.value.express_route_circuit_id, null) - peer_virtual_network_gateway_id = try(each.value.peer_virtual_network_gateway_id, null) - use_policy_based_traffic_selectors = try(each.value.use_policy_based_traffic_selectors, null) - express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) - dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) - connection_mode = try(each.value.connection_mode, null) + virtual_network_gateway_id = ( + try(each.value.virtual_network_gateway_id, null) != null ? each.value.virtual_network_gateway_id : data.azurerm_virtual_network_gateway.this[each.key].id + ) + local_network_gateway_id = ( + try(each.value.local_network_gateway_id, null) != null ? each.value.local_network_gateway_id : data.azurerm_local_network_gateway.this[each.key].id + ) + shared_key = ( + try(each.value.shared_key, null) != null ? each.value.shared_key : ( + try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null + ) + ) + enable_bgp = try(each.value.enable_bgp, null) + connection_protocol = try(each.value.connection_protocol, null) + routing_weight = try(each.value.routing_weight, null) + authorization_key = try(each.value.authorization_key, null) + express_route_circuit_id = try(each.value.express_route_circuit_id, null) + peer_virtual_network_gateway_id = try(each.value.peer_virtual_network_gateway_id, null) + use_policy_based_traffic_selectors = try(each.value.use_policy_based_traffic_selectors, null) + express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) + dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) + connection_mode = try(each.value.connection_mode, null) dynamic "ipsec_policy" { for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] From b667721f266fdf571b25267c24253ed7feccbb12 Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 14:38:31 +0100 Subject: [PATCH 48/54] fix: tags adaptation and record ovac pro tgss postgresql Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 94b323685..9dad6d919 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -32,18 +32,20 @@ resource "azurerm_virtual_network_gateway_connection" "this" { express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) connection_mode = try(each.value.connection_mode, null) - - dynamic "ipsec_policy" { - for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] - content { - dh_group = ipsec_policy.value.dh_group - ike_encryption = ipsec_policy.value.ike_encryption - ike_integrity = ipsec_policy.value.ike_integrity - ipsec_encryption = ipsec_policy.value.ipsec_encryption - ipsec_integrity = ipsec_policy.value.ipsec_integrity - pfs_group = ipsec_policy.value.pfs_group - sa_lifetime = ipsec_policy.value.sa_lifetime - sa_datasize = ipsec_policy.value.sa_datasize - } - } + dynamic "ipsec_policy" { + for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] + content { + dh_group = ipsec_policy.value.dh_group + ike_encryption = ipsec_policy.value.ike_encryption + ike_integrity = ipsec_policy.value.ike_integrity + ipsec_encryption = ipsec_policy.value.ipsec_encryption + ipsec_integrity = ipsec_policy.value.ipsec_integrity + pfs_group = ipsec_policy.value.pfs_group + sa_lifetime = ipsec_policy.value.sa_lifetime + sa_datasize = ipsec_policy.value.sa_datasize + } + } + lifecycle { + ignore_changes = [ "shared_key" ] + } } From 06b469646fa8b8c3f0d3204daab5693aa94a08e8 Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 15:47:50 +0100 Subject: [PATCH 49/54] fix: tags adaptation and record ovac pro tgss postgresql Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index 9dad6d919..af38c7202 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -46,6 +46,6 @@ resource "azurerm_virtual_network_gateway_connection" "this" { } } lifecycle { - ignore_changes = [ "shared_key" ] + ignore_changes = [ shared_key] } } From dbe55580f39cede639f460a93e4cefa4be4145b0 Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 16:26:46 +0100 Subject: [PATCH 50/54] fix: tags adaptation and record ovac pro tgss postgresql Signed-off-by: jcframil --- .../.terraform-docs.yml | 48 ++++++ .../_examples/basic_localnet/example.tf | 12 ++ .../_examples/basic_localnet/example.yaml | 10 ++ .../multiple_address_spaces/example.tf | 12 ++ .../multiple_address_spaces/example.yaml | 11 ++ .../_examples/with_tags_from_rg/example.tf | 12 ++ .../_examples/with_tags_from_rg/example.yaml | 10 ++ modules/azure-localnet-gateway/data.tf | 4 +- modules/azure-localnet-gateway/docs/footer.md | 16 ++ modules/azure-localnet-gateway/docs/header.md | 35 ++++ modules/azure-localnet-gateway/locals.tf | 2 +- modules/azure-localnet-gateway/main.tf | 14 +- .../_examples/s2s_basic/example.tf | 40 +++++ .../_examples/s2s_basic/example.yaml | 34 ++++ .../with_keyvault_shared_key/example.tf | 40 +++++ .../with_keyvault_shared_key/example.yaml | 34 ++++ .../_examples/with_nat_rules/example.tf | 40 +++++ .../_examples/with_nat_rules/example.yaml | 36 ++++ modules/azure-vnet-gateway-connection/data.tf | 36 ++-- .../docs/footer.md | 18 ++ .../docs/header.md | 63 +++++++ .../azure-vnet-gateway-connection/locals.tf | 2 +- modules/azure-vnet-gateway-connection/main.tf | 92 +++++------ .../variables.tf | 48 +++--- .../_examples/active_active_bgp/example.tf | 20 +++ .../_examples/active_active_bgp/example.yaml | 17 ++ .../_examples/basic_route_based/example.tf | 19 +++ .../_examples/basic_route_based/example.yaml | 16 ++ .../_examples/vpn_client_aad/example.tf | 22 +++ .../_examples/vpn_client_aad/example.yaml | 22 +++ modules/azure-vnet-gateway/data.tf | 5 +- modules/azure-vnet-gateway/docs/footer.md | 15 +- modules/azure-vnet-gateway/docs/header.md | 30 ++++ modules/azure-vnet-gateway/main.tf | 156 +++++++++--------- modules/azure-vnet-gateway/variables.tf | 63 +++---- modules/azure-vnet-gateway/vpn_nat_rule.tf | 4 +- 36 files changed, 838 insertions(+), 220 deletions(-) create mode 100644 modules/azure-localnet-gateway/.terraform-docs.yml create mode 100644 modules/azure-localnet-gateway/_examples/basic_localnet/example.tf create mode 100644 modules/azure-localnet-gateway/_examples/basic_localnet/example.yaml create mode 100644 modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.tf create mode 100644 modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.yaml create mode 100644 modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.tf create mode 100644 modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.yaml create mode 100644 modules/azure-localnet-gateway/docs/footer.md create mode 100644 modules/azure-localnet-gateway/docs/header.md create mode 100644 modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf create mode 100644 modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml create mode 100644 modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf create mode 100644 modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml create mode 100644 modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf create mode 100644 modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml create mode 100644 modules/azure-vnet-gateway-connection/docs/footer.md create mode 100644 modules/azure-vnet-gateway-connection/docs/header.md create mode 100644 modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf create mode 100644 modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml create mode 100644 modules/azure-vnet-gateway/_examples/basic_route_based/example.tf create mode 100644 modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml create mode 100644 modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf create mode 100644 modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml diff --git a/modules/azure-localnet-gateway/.terraform-docs.yml b/modules/azure-localnet-gateway/.terraform-docs.yml new file mode 100644 index 000000000..3a69365ff --- /dev/null +++ b/modules/azure-localnet-gateway/.terraform-docs.yml @@ -0,0 +1,48 @@ +formatter: "markdown" + +version: "" + +header-from: docs/header.md +footer-from: docs/footer.md + +recursive: + enabled: false + path: modules + include-main: true + +sections: + hide: [] + show: [] + +content: "" + +output: + file: "README.md" + mode: inject + template: |- + + {{ .Content }} + + +output-values: + enabled: false + from: "" + +sort: + enabled: true + by: name + +settings: + anchor: true + color: true + default: true + description: false + escape: true + hide-empty: false + html: true + indent: 2 + lockfile: true + read-comments: true + required: true + sensitive: true + type: true diff --git a/modules/azure-localnet-gateway/_examples/basic_localnet/example.tf b/modules/azure-localnet-gateway/_examples/basic_localnet/example.tf new file mode 100644 index 000000000..474c3870a --- /dev/null +++ b/modules/azure-localnet-gateway/_examples/basic_localnet/example.tf @@ -0,0 +1,12 @@ +module "localnet_gateway" { + source = "../../" + localnet = [{ + local_gateway_name = "example-local-gw" + location = "westeurope" + resource_group_name = "example-rg" + local_gateway_ip = "203.0.113.1" + local_gateway_address_space = ["10.1.0.0/16"] + tags_from_rg = false + tags = { environment = "dev" } + }] +} diff --git a/modules/azure-localnet-gateway/_examples/basic_localnet/example.yaml b/modules/azure-localnet-gateway/_examples/basic_localnet/example.yaml new file mode 100644 index 000000000..6e973afeb --- /dev/null +++ b/modules/azure-localnet-gateway/_examples/basic_localnet/example.yaml @@ -0,0 +1,10 @@ +localnet: + - local_gateway_name: example-local-gw + location: westeurope + resource_group_name: example-rg + local_gateway_ip: 203.0.113.1 + local_gateway_address_space: + - 10.1.0.0/16 + tags_from_rg: false + tags: + environment: dev diff --git a/modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.tf b/modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.tf new file mode 100644 index 000000000..d142b1358 --- /dev/null +++ b/modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.tf @@ -0,0 +1,12 @@ +module "localnet_gateway" { + source = "../../" + localnet = [{ + local_gateway_name = "multi-space-gw" + location = "westeurope" + resource_group_name = "example-rg" + local_gateway_ip = "203.0.113.2" + local_gateway_address_space = ["10.1.0.0/16", "10.2.0.0/16"] + tags_from_rg = false + tags = { environment = "test" } + }] +} diff --git a/modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.yaml b/modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.yaml new file mode 100644 index 000000000..f5575e07c --- /dev/null +++ b/modules/azure-localnet-gateway/_examples/multiple_address_spaces/example.yaml @@ -0,0 +1,11 @@ +localnet: + - local_gateway_name: multi-space-gw + location: westeurope + resource_group_name: example-rg + local_gateway_ip: 203.0.113.2 + local_gateway_address_space: + - 10.1.0.0/16 + - 10.2.0.0/16 + tags_from_rg: false + tags: + environment: test diff --git a/modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.tf b/modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.tf new file mode 100644 index 000000000..a9a04d4df --- /dev/null +++ b/modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.tf @@ -0,0 +1,12 @@ +module "localnet_gateway" { + source = "../../" + localnet = [{ + local_gateway_name = "tagged-gw" + location = "westeurope" + resource_group_name = "example-rg" + local_gateway_ip = "203.0.113.3" + local_gateway_address_space = ["10.3.0.0/16"] + tags_from_rg = true + tags = { custom = "yes" } + }] +} diff --git a/modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.yaml b/modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.yaml new file mode 100644 index 000000000..5401add82 --- /dev/null +++ b/modules/azure-localnet-gateway/_examples/with_tags_from_rg/example.yaml @@ -0,0 +1,10 @@ +localnet: + - local_gateway_name: tagged-gw + location: westeurope + resource_group_name: example-rg + local_gateway_ip: 203.0.113.3 + local_gateway_address_space: + - 10.3.0.0/16 + tags_from_rg: true + tags: + custom: "yes" diff --git a/modules/azure-localnet-gateway/data.tf b/modules/azure-localnet-gateway/data.tf index 6760bcf0e..5a4e55297 100644 --- a/modules/azure-localnet-gateway/data.tf +++ b/modules/azure-localnet-gateway/data.tf @@ -2,6 +2,6 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network data "azurerm_resource_group" "this" { - for_each = { for idx, s in var.localnet : idx => s } - name = each.value.resource_group_name + for_each = { for idx, s in var.localnet : idx => s } + name = each.value.resource_group_name } diff --git a/modules/azure-localnet-gateway/docs/footer.md b/modules/azure-localnet-gateway/docs/footer.md new file mode 100644 index 000000000..b4e31edc1 --- /dev/null +++ b/modules/azure-localnet-gateway/docs/footer.md @@ -0,0 +1,16 @@ +## Examples + +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples): + +- [basic_localnet](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples/basic_localnet) - Basic local network gateway example. +- [multiple_address_spaces](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples/multiple_address_spaces) - Example with multiple address spaces. +- [with_tags_from_rg](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples/with_tags_from_rg) - Example inheriting tags from the resource group. + +## Remote resources + +- **Azure Local Network Gateway**: [azurerm_local_network_gateway documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway) +- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + +## Support + +For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). diff --git a/modules/azure-localnet-gateway/docs/header.md b/modules/azure-localnet-gateway/docs/header.md new file mode 100644 index 000000000..0f2997113 --- /dev/null +++ b/modules/azure-localnet-gateway/docs/header.md @@ -0,0 +1,35 @@ +# **Azure Local Network Gateway Terraform Module** + +## Overview + +This module provisions and manages Azure Local Network Gateways for Site-to-Site VPN connections using the [azurerm_local_network_gateway](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway) resource. It is suitable for production, staging, and development environments, y puede integrarse en proyectos Terraform más grandes o usarse de forma independiente. + +## Key Features + +- **Multiple Gateway Support**: Create one or more Azure Local Network Gateways with flexible configuration. +- **Custom Address Spaces**: Define custom address spaces and gateway IPs for each local network. +- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. +- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. + +## Basic Usage + +See the main README and the `_examples/` directory for usage examples. + +```hcl +module "localnet_gateway" { + source = "./modules/azure-localnet-gateway" + localnet = [ + { + local_gateway_name = "example-gateway" + location = "westeurope" + resource_group_name = "example-rg" + local_gateway_ip = "203.0.113.1" + local_gateway_address_space = ["10.1.0.0/16"] + tags_from_rg = true + tags = { + environment = "dev" + } + } + ] +} +``` diff --git a/modules/azure-localnet-gateway/locals.tf b/modules/azure-localnet-gateway/locals.tf index e0f897db1..9d87d5e2f 100644 --- a/modules/azure-localnet-gateway/locals.tf +++ b/modules/azure-localnet-gateway/locals.tf @@ -1,7 +1,7 @@ ## LOCALS SECTION locals { - # tags por cada localnet (key = idx) + # Handle tags based on whether to use resource group tags or module-defined tags for each local network gateway (key = idx) tags = { for idx, s in var.localnet : idx => ( coalesce(s.tags_from_rg, false) diff --git a/modules/azure-localnet-gateway/main.tf b/modules/azure-localnet-gateway/main.tf index d729a12b6..5832ca34e 100644 --- a/modules/azure-localnet-gateway/main.tf +++ b/modules/azure-localnet-gateway/main.tf @@ -2,11 +2,11 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway resource "azurerm_local_network_gateway" "this" { - for_each = { for idx, s in var.localnet : idx => s } - name = each.value.local_gateway_name - location = each.value.location - resource_group_name = each.value.resource_group_name - gateway_address = each.value.local_gateway_ip - address_space = each.value.local_gateway_address_space - tags = local.tags[each.key] + for_each = { for idx, s in var.localnet : idx => s } + name = each.value.local_gateway_name + location = each.value.location + resource_group_name = each.value.resource_group_name + gateway_address = each.value.local_gateway_ip + address_space = each.value.local_gateway_address_space + tags = local.tags[each.key] } diff --git a/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf b/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf new file mode 100644 index 000000000..92c2f1f36 --- /dev/null +++ b/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf @@ -0,0 +1,40 @@ +module "vnet_gateway_connection" { + source = "../../" + connection = [{ + name = "example-connection" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vnet-gw" + local_gateway_name = "example-local-gw" + local_gateway_resource_group_name = "example-local-rg" + keyvault_vault_name = "example-kv" + keyvault_vault_rg = "example-kv-rg" + keyvault_secret_name = "vpn-shared-key" + type = "IPsec" + connection_mode = "InitiatorOnly" + connection_protocol = "IKEv2" + enable_bgp = false + express_route_gateway_bypass = false + dpd_timeout_seconds = 30 + routing_weight = 0 + use_policy_based_traffic_selectors = false + ipsec_policy = { + dh_group = "DHGroup14" + ike_encryption = "AES256" + ike_integrity = "SHA256" + ipsec_encryption = "AES256" + ipsec_integrity = "SHA256" + pfs_group = "PFS2" + sa_datasize = 0 + sa_lifetime = 28800 + } + egress_nat_rule_ids = [] + ingress_nat_rule_ids = [] + local_azure_ip_address_enabled = false + tags_from_rg = true + tags = { + environment = "dev" + application = "example-app" + } + }] +} diff --git a/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml b/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml new file mode 100644 index 000000000..a52958dad --- /dev/null +++ b/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml @@ -0,0 +1,34 @@ +connection: + - name: example-connection + location: westeurope + resource_group_name: example-rg + gateway_name: example-vnet-gw + local_gateway_name: example-local-gw + local_gateway_resource_group_name: example-local-rg + keyvault_vault_name: example-kv + keyvault_vault_rg: example-kv-rg + keyvault_secret_name: vpn-shared-key + type: IPsec + connection_mode: InitiatorOnly + connection_protocol: IKEv2 + enable_bgp: false + express_route_gateway_bypass: false + dpd_timeout_seconds: 30 + routing_weight: 0 + use_policy_based_traffic_selectors: false + ipsec_policy: + dh_group: DHGroup14 + ike_encryption: AES256 + ike_integrity: SHA256 + ipsec_encryption: AES256 + ipsec_integrity: SHA256 + pfs_group: PFS2 + sa_datasize: 0 + sa_lifetime: 28800 + egress_nat_rule_ids: [] + ingress_nat_rule_ids: [] + local_azure_ip_address_enabled: false + tags_from_rg: true + tags: + environment: dev + application: example-app diff --git a/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf b/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf new file mode 100644 index 000000000..bf739db15 --- /dev/null +++ b/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf @@ -0,0 +1,40 @@ +module "vnet_gateway_connection" { + source = "../../" + connection = [{ + name = "keyvault-connection" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vnet-gw" + local_gateway_name = "example-local-gw" + local_gateway_resource_group_name = "example-local-rg" + keyvault_vault_name = "example-kv" + keyvault_vault_rg = "example-kv-rg" + keyvault_secret_name = "vpn-shared-key" + type = "IPsec" + connection_mode = "InitiatorOnly" + connection_protocol = "IKEv2" + enable_bgp = false + express_route_gateway_bypass = false + dpd_timeout_seconds = 30 + routing_weight = 0 + use_policy_based_traffic_selectors = false + ipsec_policy = { + dh_group = "DHGroup14" + ike_encryption = "AES256" + ike_integrity = "SHA256" + ipsec_encryption = "AES256" + ipsec_integrity = "SHA256" + pfs_group = "PFS2" + sa_datasize = 0 + sa_lifetime = 28800 + } + egress_nat_rule_ids = [] + ingress_nat_rule_ids = [] + local_azure_ip_address_enabled = false + tags_from_rg = true + tags = { + environment = "prod" + application = "keyvault-app" + } + }] +} diff --git a/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml b/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml new file mode 100644 index 000000000..abe5f4694 --- /dev/null +++ b/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml @@ -0,0 +1,34 @@ +connection: + - name: keyvault-connection + location: westeurope + resource_group_name: example-rg + gateway_name: example-vnet-gw + local_gateway_name: example-local-gw + local_gateway_resource_group_name: example-local-rg + keyvault_vault_name: example-kv + keyvault_vault_rg: example-kv-rg + keyvault_secret_name: vpn-shared-key + type: IPsec + connection_mode: InitiatorOnly + connection_protocol: IKEv2 + enable_bgp: false + express_route_gateway_bypass: false + dpd_timeout_seconds: 30 + routing_weight: 0 + use_policy_based_traffic_selectors: false + ipsec_policy: + dh_group: DHGroup14 + ike_encryption: AES256 + ike_integrity: SHA256 + ipsec_encryption: AES256 + ipsec_integrity: SHA256 + pfs_group: PFS2 + sa_datasize: 0 + sa_lifetime: 28800 + egress_nat_rule_ids: [] + ingress_nat_rule_ids: [] + local_azure_ip_address_enabled: false + tags_from_rg: true + tags: + environment: prod + application: keyvault-app diff --git a/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf b/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf new file mode 100644 index 000000000..003d456d7 --- /dev/null +++ b/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf @@ -0,0 +1,40 @@ +module "vnet_gateway_connection" { + source = "../../" + connection = [{ + name = "nat-connection" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vnet-gw" + local_gateway_name = "example-local-gw" + local_gateway_resource_group_name = "example-local-rg" + keyvault_vault_name = "example-kv" + keyvault_vault_rg = "example-kv-rg" + keyvault_secret_name = "vpn-shared-key" + type = "IPsec" + connection_mode = "InitiatorOnly" + connection_protocol = "IKEv2" + enable_bgp = false + express_route_gateway_bypass = false + dpd_timeout_seconds = 30 + routing_weight = 0 + use_policy_based_traffic_selectors = false + ipsec_policy = { + dh_group = "DHGroup14" + ike_encryption = "AES256" + ike_integrity = "SHA256" + ipsec_encryption = "AES256" + ipsec_integrity = "SHA256" + pfs_group = "PFS2" + sa_datasize = 0 + sa_lifetime = 28800 + } + egress_nat_rule_ids = ["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/egress_nat"] + ingress_nat_rule_ids = ["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/ingress_nat"] + local_azure_ip_address_enabled = false + tags_from_rg = false + tags = { + environment = "test" + application = "nat-app" + } + }] +} diff --git a/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml b/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml new file mode 100644 index 000000000..7b372f0dd --- /dev/null +++ b/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml @@ -0,0 +1,36 @@ +connection: + - name: nat-connection + location: westeurope + resource_group_name: example-rg + gateway_name: example-vnet-gw + local_gateway_name: example-local-gw + local_gateway_resource_group_name: example-local-rg + keyvault_vault_name: example-kv + keyvault_vault_rg: example-kv-rg + keyvault_secret_name: vpn-shared-key + type: IPsec + connection_mode: InitiatorOnly + connection_protocol: IKEv2 + enable_bgp: false + express_route_gateway_bypass: false + dpd_timeout_seconds: 30 + routing_weight: 0 + use_policy_based_traffic_selectors: false + ipsec_policy: + dh_group: DHGroup14 + ike_encryption: AES256 + ike_integrity: SHA256 + ipsec_encryption: AES256 + ipsec_integrity: SHA256 + pfs_group: PFS2 + sa_datasize: 0 + sa_lifetime: 28800 + egress_nat_rule_ids: + - /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/egress_nat + ingress_nat_rule_ids: + - /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/ingress_nat + local_azure_ip_address_enabled: false + tags_from_rg: false + tags: + environment: test + application: nat-app diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf index 5dfbc638c..cc555cd97 100644 --- a/modules/azure-vnet-gateway-connection/data.tf +++ b/modules/azure-vnet-gateway-connection/data.tf @@ -1,33 +1,35 @@ ## DATA SOURCES SECTION -# Data source para local network gateway +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group data "azurerm_local_network_gateway" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.local_gateway_name - resource_group_name = each.value.local_gateway_resource_group_name + for_each = { for idx, s in var.connection : idx => s } + name = each.value.local_gateway_name + resource_group_name = each.value.local_gateway_resource_group_name } -# Iterar sobre cada conexión para los data sources +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network_gateway data "azurerm_resource_group" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.resource_group_name + for_each = { for idx, s in var.connection : idx => s } + name = each.value.resource_group_name } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network_gateway data "azurerm_virtual_network_gateway" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.gateway_name - resource_group_name = each.value.resource_group_name + for_each = { for idx, s in var.connection : idx => s } + name = each.value.gateway_name + resource_group_name = each.value.resource_group_name } -# Optionally fetch shared_key from Key Vault if secret_name and vault info are provided +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret data "azurerm_key_vault_secret" "s2s" { - for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_secret_name - key_vault_id = data.azurerm_key_vault.s2s[each.key].id + for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_secret_name + key_vault_id = data.azurerm_key_vault.s2s[each.key].id } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault data "azurerm_key_vault" "s2s" { - for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_vault_name - resource_group_name = each.value.keyvault_vault_rg + for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } + name = each.value.keyvault_vault_name + resource_group_name = each.value.keyvault_vault_rg } diff --git a/modules/azure-vnet-gateway-connection/docs/footer.md b/modules/azure-vnet-gateway-connection/docs/footer.md new file mode 100644 index 000000000..28e1ccacb --- /dev/null +++ b/modules/azure-vnet-gateway-connection/docs/footer.md @@ -0,0 +1,18 @@ + +## Examples + +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples): + +- [s2s_basic](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/s2s_basic) - Basic Site-to-Site connection example. +- [with_nat_rules](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with_nat_rules) - Example with ingress/egress NAT rules. +- [with_keyvault](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with_keyvault) - Example using Azure Key Vault for shared key management. + +## Remote resources + +- **Azure Virtual Network Gateway Connection**: [azurerm_virtual_network_gateway_connection documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection) +- **Azure Key Vault Secret**: [azurerm_key_vault_secret documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) +- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + +## Support + +For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). diff --git a/modules/azure-vnet-gateway-connection/docs/header.md b/modules/azure-vnet-gateway-connection/docs/header.md new file mode 100644 index 000000000..49162221f --- /dev/null +++ b/modules/azure-vnet-gateway-connection/docs/header.md @@ -0,0 +1,63 @@ +# **Azure Virtual Network Gateway Connection Terraform Module** + +## Overview + +This module provisions and manages Azure Virtual Network Gateway Connections for Site-to-Site (S2S), VNet-to-VNet, and ExpressRoute VPNs. It supports advanced configuration, including custom IPsec/IKE policies, NAT rules, BGP, and shared key management via Azure Key Vault. + +It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. + +## Key Features + +- **S2S, VNet-to-VNet, and ExpressRoute Support**: Create connections between Azure VNets, on-premises networks, or ExpressRoute circuits. +- **Custom IPsec/IKE Policies**: Fine-grained control over encryption, integrity, and key exchange settings. +- **NAT Rule Integration**: Attach ingress and egress NAT rules to connections. +- **Key Vault Integration**: Securely manage shared keys using Azure Key Vault. +- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. +- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. + +## Basic Usage + +See the main README and the `_examples/` directory for usage examples. + +```hcl +module "vnet_gateway_connection" { + source = "./modules/azure-vnet-gateway-connection" + connection = [{ + name = "example-connection" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vnet-gw" + local_gateway_name = "example-local-gw" + local_gateway_resource_group_name = "example-local-rg" + keyvault_vault_name = "example-kv" + keyvault_vault_rg = "example-kv-rg" + keyvault_secret_name = "vpn-shared-key" + type = "IPsec" + connection_mode = "InitiatorOnly" + connection_protocol = "IKEv2" + enable_bgp = false + express_route_gateway_bypass = false + dpd_timeout_seconds = 30 + routing_weight = 0 + use_policy_based_traffic_selectors = false + ipsec_policy = { + dh_group = "DHGroup14" + ike_encryption = "AES256" + ike_integrity = "SHA256" + ipsec_encryption = "AES256" + ipsec_integrity = "SHA256" + pfs_group = "PFS2" + sa_datasize = 0 + sa_lifetime = 28800 + } + egress_nat_rule_ids = [] + ingress_nat_rule_ids = [] + local_azure_ip_address_enabled = false + tags_from_rg = true + tags = { + environment = "dev" + application = "example-app" + } + }] +} +``` diff --git a/modules/azure-vnet-gateway-connection/locals.tf b/modules/azure-vnet-gateway-connection/locals.tf index e257bf436..4540baa34 100644 --- a/modules/azure-vnet-gateway-connection/locals.tf +++ b/modules/azure-vnet-gateway-connection/locals.tf @@ -1,7 +1,7 @@ ## LOCALS SECTION locals { - # tags por cada connection (key = idx), siempre map(string) + # Handle tags based on whether to use resource group tags or module-defined tags for each connection (key = idx) tags = { for idx, s in var.connection : idx => ( coalesce(s.tags_from_rg, false) diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf index af38c7202..628e22256 100644 --- a/modules/azure-vnet-gateway-connection/main.tf +++ b/modules/azure-vnet-gateway-connection/main.tf @@ -2,50 +2,50 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection resource "azurerm_virtual_network_gateway_connection" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.name - location = each.value.location - resource_group_name = each.value.resource_group_name - egress_nat_rule_ids = try(each.value.egress_nat_rule_ids, null) - ingress_nat_rule_ids = try(each.value.ingress_nat_rule_ids, null) - local_azure_ip_address_enabled = try(each.value.local_azure_ip_address_enabled, null) - tags = local.tags[each.key] - type = each.value.type - virtual_network_gateway_id = ( - try(each.value.virtual_network_gateway_id, null) != null ? each.value.virtual_network_gateway_id : data.azurerm_virtual_network_gateway.this[each.key].id - ) - local_network_gateway_id = ( - try(each.value.local_network_gateway_id, null) != null ? each.value.local_network_gateway_id : data.azurerm_local_network_gateway.this[each.key].id - ) - shared_key = ( - try(each.value.shared_key, null) != null ? each.value.shared_key : ( - try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null - ) - ) - enable_bgp = try(each.value.enable_bgp, null) - connection_protocol = try(each.value.connection_protocol, null) - routing_weight = try(each.value.routing_weight, null) - authorization_key = try(each.value.authorization_key, null) - express_route_circuit_id = try(each.value.express_route_circuit_id, null) - peer_virtual_network_gateway_id = try(each.value.peer_virtual_network_gateway_id, null) - use_policy_based_traffic_selectors = try(each.value.use_policy_based_traffic_selectors, null) - express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) - dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) - connection_mode = try(each.value.connection_mode, null) - dynamic "ipsec_policy" { - for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] - content { - dh_group = ipsec_policy.value.dh_group - ike_encryption = ipsec_policy.value.ike_encryption - ike_integrity = ipsec_policy.value.ike_integrity - ipsec_encryption = ipsec_policy.value.ipsec_encryption - ipsec_integrity = ipsec_policy.value.ipsec_integrity - pfs_group = ipsec_policy.value.pfs_group - sa_lifetime = ipsec_policy.value.sa_lifetime - sa_datasize = ipsec_policy.value.sa_datasize - } - } - lifecycle { - ignore_changes = [ shared_key] - } + for_each = { for idx, s in var.connection : idx => s } + name = each.value.name + location = each.value.location + resource_group_name = each.value.resource_group_name + egress_nat_rule_ids = try(each.value.egress_nat_rule_ids, null) + ingress_nat_rule_ids = try(each.value.ingress_nat_rule_ids, null) + local_azure_ip_address_enabled = try(each.value.local_azure_ip_address_enabled, null) + tags = local.tags[each.key] + type = each.value.type + virtual_network_gateway_id = ( + try(each.value.virtual_network_gateway_id, null) != null ? each.value.virtual_network_gateway_id : data.azurerm_virtual_network_gateway.this[each.key].id + ) + local_network_gateway_id = ( + try(each.value.local_network_gateway_id, null) != null ? each.value.local_network_gateway_id : data.azurerm_local_network_gateway.this[each.key].id + ) + shared_key = ( + try(each.value.shared_key, null) != null ? each.value.shared_key : ( + try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null + ) + ) + enable_bgp = try(each.value.enable_bgp, null) + connection_protocol = try(each.value.connection_protocol, null) + routing_weight = try(each.value.routing_weight, null) + authorization_key = try(each.value.authorization_key, null) + express_route_circuit_id = try(each.value.express_route_circuit_id, null) + peer_virtual_network_gateway_id = try(each.value.peer_virtual_network_gateway_id, null) + use_policy_based_traffic_selectors = try(each.value.use_policy_based_traffic_selectors, null) + express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) + dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) + connection_mode = try(each.value.connection_mode, null) + dynamic "ipsec_policy" { + for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] + content { + dh_group = ipsec_policy.value.dh_group + ike_encryption = ipsec_policy.value.ike_encryption + ike_integrity = ipsec_policy.value.ike_integrity + ipsec_encryption = ipsec_policy.value.ipsec_encryption + ipsec_integrity = ipsec_policy.value.ipsec_integrity + pfs_group = ipsec_policy.value.pfs_group + sa_lifetime = ipsec_policy.value.sa_lifetime + sa_datasize = ipsec_policy.value.sa_datasize + } + } + lifecycle { + ignore_changes = [shared_key] + } } diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf index fbb870542..aae452cc0 100644 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ b/modules/azure-vnet-gateway-connection/variables.tf @@ -3,33 +3,33 @@ variable "connection" { description = "List of Site-to-Site VPN connection objects" type = list(object({ - name = string - location = string - resource_group_name = string - local_gateway_name = string - local_gateway_resource_group_name = string - type = string - gateway_name = string - shared_key = optional(string) - keyvault_secret_name = optional(string) - keyvault_vault_name = optional(string) - keyvault_vault_rg = optional(string) - virtual_network_gateway_id = optional(string) - local_network_gateway_id = optional(string) - connection_protocol = optional(string) - routing_weight = optional(number) - authorization_key = optional(string) - express_route_circuit_id = optional(string) - peer_virtual_network_gateway_id = optional(string) - use_policy_based_traffic_selectors = optional(bool) - express_route_gateway_bypass = optional(bool) - dpd_timeout_seconds = optional(number) - connection_mode = optional(string) - tags_from_rg = optional(bool) + name = string + location = string + resource_group_name = string + local_gateway_name = string + local_gateway_resource_group_name = string + type = string + gateway_name = string + shared_key = optional(string) + keyvault_secret_name = optional(string) + keyvault_vault_name = optional(string) + keyvault_vault_rg = optional(string) + virtual_network_gateway_id = optional(string) + local_network_gateway_id = optional(string) + connection_protocol = optional(string) + routing_weight = optional(number) + authorization_key = optional(string) + express_route_circuit_id = optional(string) + peer_virtual_network_gateway_id = optional(string) + use_policy_based_traffic_selectors = optional(bool) + express_route_gateway_bypass = optional(bool) + dpd_timeout_seconds = optional(number) + connection_mode = optional(string) + tags_from_rg = optional(bool) egress_nat_rule_ids = optional(list(string)) ingress_nat_rule_ids = optional(list(string)) local_azure_ip_address_enabled = optional(bool) - tags = optional(map(string)) + tags = optional(map(string)) ipsec_policy = optional(object({ dh_group = string ike_encryption = string diff --git a/modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf b/modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf new file mode 100644 index 000000000..35f82a9bc --- /dev/null +++ b/modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf @@ -0,0 +1,20 @@ +module "vnet_gateway" { + source = "../../" + vpn = { + vnet_name = "example-vnet" + gateway_subnet_name = "GatewaySubnet" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vpn-gw" + ip_name = "example-vpn-ip" + public_ip_name = "example-vpn-public-ip" + ip_allocation_method = "Dynamic" + type = "Vpn" + vpn_type = "RouteBased" + active_active = true + enable_bgp = true + sku = "VpnGw2" + bgp_route_translation_for_nat_enabled = true + tags = { environment = "prod" } + } +} diff --git a/modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml b/modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml new file mode 100644 index 000000000..c085af599 --- /dev/null +++ b/modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml @@ -0,0 +1,17 @@ +vpn: + vnet_name: example-vnet + gateway_subnet_name: GatewaySubnet + location: westeurope + resource_group_name: example-rg + gateway_name: example-vpn-gw + ip_name: example-vpn-ip + public_ip_name: example-vpn-public-ip + ip_allocation_method: Dynamic + type: Vpn + vpn_type: RouteBased + active_active: true + enable_bgp: true + sku: VpnGw2 + bgp_route_translation_for_nat_enabled: true + tags: + environment: prod diff --git a/modules/azure-vnet-gateway/_examples/basic_route_based/example.tf b/modules/azure-vnet-gateway/_examples/basic_route_based/example.tf new file mode 100644 index 000000000..c12d46377 --- /dev/null +++ b/modules/azure-vnet-gateway/_examples/basic_route_based/example.tf @@ -0,0 +1,19 @@ +module "vnet_gateway" { + source = "../../" + vpn = { + vnet_name = "example-vnet" + gateway_subnet_name = "GatewaySubnet" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vpn-gw" + ip_name = "example-vpn-ip" + public_ip_name = "example-vpn-public-ip" + ip_allocation_method = "Dynamic" + type = "Vpn" + vpn_type = "RouteBased" + active_active = false + enable_bgp = false + sku = "VpnGw1" + tags = { environment = "dev" } + } +} diff --git a/modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml b/modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml new file mode 100644 index 000000000..f8b8eead6 --- /dev/null +++ b/modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml @@ -0,0 +1,16 @@ +vpn: + vnet_name: example-vnet + gateway_subnet_name: GatewaySubnet + location: westeurope + resource_group_name: example-rg + gateway_name: example-vpn-gw + ip_name: example-vpn-ip + public_ip_name: example-vpn-public-ip + ip_allocation_method: Dynamic + type: Vpn + vpn_type: RouteBased + active_active: false + enable_bgp: false + sku: VpnGw1 + tags: + environment: dev diff --git a/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf b/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf new file mode 100644 index 000000000..2e8e1feab --- /dev/null +++ b/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf @@ -0,0 +1,22 @@ +module "vnet_gateway" { + source = "../../" + vpn = { + vnet_name = "example-vnet" + gateway_subnet_name = "GatewaySubnet" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vpn-gw" + ip_name = "example-vpn-ip" + public_ip_name = "example-vpn-public-ip" + ip_allocation_method = "Dynamic" + type = "Vpn" + vpn_type = "RouteBased" + active_active = false + enable_bgp = false + sku = "VpnGw1" + vpn_client_address_space = ["10.10.0.0/24"] + vpn_client_protocols = ["IkeV2", "OpenVPN"] + vpn_client_aad_tenant = "https://login.microsoftonline.com/" + tags = { environment = "test" } + } +} diff --git a/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml b/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml new file mode 100644 index 000000000..e66fab766 --- /dev/null +++ b/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml @@ -0,0 +1,22 @@ +vpn: + vnet_name: example-vnet + gateway_subnet_name: GatewaySubnet + location: westeurope + resource_group_name: example-rg + gateway_name: example-vpn-gw + ip_name: example-vpn-ip + public_ip_name: example-vpn-public-ip + ip_allocation_method: Dynamic + type: Vpn + vpn_type: RouteBased + active_active: false + enable_bgp: false + sku: VpnGw1 + vpn_client_address_space: + - 10.10.0.0/24 + vpn_client_protocols: + - IkeV2 + - OpenVPN + vpn_client_aad_tenant: https://login.microsoftonline.com/ + tags: + environment: test diff --git a/modules/azure-vnet-gateway/data.tf b/modules/azure-vnet-gateway/data.tf index 2734ae91b..be11ff191 100644 --- a/modules/azure-vnet-gateway/data.tf +++ b/modules/azure-vnet-gateway/data.tf @@ -1,21 +1,24 @@ ## DATA SOURCES SECTION -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group data "azurerm_resource_group" "this" { name = var.vpn.resource_group_name } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet data "azurerm_subnet" "this" { name = var.vpn.gateway_subnet_name virtual_network_name = var.vpn.vnet_name resource_group_name = var.vpn.resource_group_name } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/public_ip data "azurerm_public_ip" "this" { name = var.vpn.public_ip_name resource_group_name = var.vpn.resource_group_name } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network_gateway data "azurerm_virtual_network_gateway" "this" { name = var.vpn.gateway_name resource_group_name = var.vpn.resource_group_name diff --git a/modules/azure-vnet-gateway/docs/footer.md b/modules/azure-vnet-gateway/docs/footer.md index d80c961a5..f550568b2 100644 --- a/modules/azure-vnet-gateway/docs/footer.md +++ b/modules/azure-vnet-gateway/docs/footer.md @@ -1,19 +1,14 @@ - - ## Examples -For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples): +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples): -- [with_nic](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples/with_nic) - Example using Azure Key Vault for admin password and custom network interface configuration. -- [with_custom_data](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples/with_custom_data) - Example provisioning a VM with custom PowerShell data. -- [with_vault_admin_pass](https://github.com/prefapp/tfm/tree/main/modules/azure-windows-vm/_examples/with_vault_admin_pass) - Example using Key Vault to securely provide the VM admin password. -- You can also use the module to attach additional unmanaged data disks to your VM (see documentation for details). +- [basic_route_based](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/basic_route_based) - Basic RouteBased gateway example. +- [active_active_bgp](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/active_active_bgp) - Active-Active gateway with BGP enabled. +- [vpn_client_aad](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/vpn_client_aad) - Gateway with VPN Client and Azure AD authentication. ## Remote resources -- **Azure Windows Virtual Machine**: [azurerm_windows_virtual_machine documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) -- **Azure Network Interface**: [azurerm_network_interface documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) -- **Azure Key Vault**: [azurerm_key_vault documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) +- **Azure Virtual Network Gateway**: [azurerm_virtual_network_gateway documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway) - **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) ## Support diff --git a/modules/azure-vnet-gateway/docs/header.md b/modules/azure-vnet-gateway/docs/header.md index d0a6367ba..24e2ba402 100644 --- a/modules/azure-vnet-gateway/docs/header.md +++ b/modules/azure-vnet-gateway/docs/header.md @@ -2,8 +2,38 @@ ## Overview +This module provisions and manages an Azure Virtual Network Gateway for VPN connectivity, supporting both Route-based and Policy-based configurations. It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. ## Key Features +- **Flexible Gateway Deployment**: Supports Route-based and Policy-based VPN gateways, active-active mode, and multiple SKUs. +- **Custom IP Configuration**: Allows custom public IP, subnet, and private IP allocation. +- **Advanced VPN Client Support**: Configure VPN client address spaces, protocols, and AAD integration for P2S. +- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. +- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. ## Basic Usage + +See the main README and the `_examples/` directory for usage examples. + +```hcl +module "vnet_gateway" { + source = "./modules/azure-vnet-gateway" + vpn = { + vnet_name = "my-vnet" + gateway_subnet_name = "GatewaySubnet" + location = "westeurope" + resource_group_name = "my-rg" + gateway_name = "my-vpn-gw" + ip_name = "my-vpn-ip" + public_ip_name = "my-vpn-public-ip" + ip_allocation_method = "Dynamic" + type = "Vpn" + vpn_type = "RouteBased" + active_active = false + enable_bgp = false + sku = "VpnGw1" + # ...other optional fields... + } +} +``` diff --git a/modules/azure-vnet-gateway/main.tf b/modules/azure-vnet-gateway/main.tf index 7a776e359..c59cac56b 100644 --- a/modules/azure-vnet-gateway/main.tf +++ b/modules/azure-vnet-gateway/main.tf @@ -2,87 +2,87 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway resource "azurerm_virtual_network_gateway" "this" { - name = var.vpn.gateway_name - location = var.vpn.location - resource_group_name = var.vpn.resource_group_name - type = var.vpn.type - vpn_type = var.vpn.vpn_type - sku = var.vpn.sku - tags = local.tags - active_active = var.vpn.active_active - enable_bgp = var.vpn.enable_bgp - generation = var.vpn.generation - default_local_network_gateway_id = var.vpn.default_local_network_gateway_id - edge_zone = var.vpn.edge_zone - private_ip_address_enabled = var.vpn.private_ip_address_enabled - bgp_route_translation_for_nat_enabled = var.vpn.bgp_route_translation_for_nat_enabled - dns_forwarding_enabled = var.vpn.dns_forwarding_enabled - ip_sec_replay_protection_enabled = var.vpn.ip_sec_replay_protection_enabled - remote_vnet_traffic_enabled = var.vpn.remote_vnet_traffic_enabled - virtual_wan_traffic_enabled = var.vpn.virtual_wan_traffic_enabled + name = var.vpn.gateway_name + location = var.vpn.location + resource_group_name = var.vpn.resource_group_name + type = var.vpn.type + vpn_type = var.vpn.vpn_type + sku = var.vpn.sku + tags = local.tags + active_active = var.vpn.active_active + enable_bgp = var.vpn.enable_bgp + generation = var.vpn.generation + default_local_network_gateway_id = var.vpn.default_local_network_gateway_id + edge_zone = var.vpn.edge_zone + private_ip_address_enabled = var.vpn.private_ip_address_enabled + bgp_route_translation_for_nat_enabled = var.vpn.bgp_route_translation_for_nat_enabled + dns_forwarding_enabled = var.vpn.dns_forwarding_enabled + ip_sec_replay_protection_enabled = var.vpn.ip_sec_replay_protection_enabled + remote_vnet_traffic_enabled = var.vpn.remote_vnet_traffic_enabled + virtual_wan_traffic_enabled = var.vpn.virtual_wan_traffic_enabled - ip_configuration { - name = var.vpn.ip_name - subnet_id = data.azurerm_subnet.this.id - public_ip_address_id = data.azurerm_public_ip.this.id - private_ip_address_allocation = var.vpn.private_ip_address_allocation - } + ip_configuration { + name = var.vpn.ip_name + subnet_id = data.azurerm_subnet.this.id + public_ip_address_id = data.azurerm_public_ip.this.id + private_ip_address_allocation = var.vpn.private_ip_address_allocation + } - custom_route { - address_prefixes = var.vpn.custom_route_address_prefixes - } + custom_route { + address_prefixes = var.vpn.custom_route_address_prefixes + } - dynamic "vpn_client_configuration" { - for_each = length(var.vpn.vpn_client_address_space) > 0 ? [1] : [] - content { - address_space = var.vpn.vpn_client_address_space - vpn_client_protocols = var.vpn.vpn_client_protocols - aad_tenant = var.vpn.vpn_client_aad_tenant - aad_audience = var.vpn.vpn_client_aad_audience - aad_issuer = var.vpn.vpn_client_aad_issuer - dynamic "root_certificate" { - for_each = var.vpn.root_certificates - content { - name = root_certificate.value.name - public_cert_data = coalesce( - root_certificate.value.public_cert_data, - root_certificate.value.public_cert - ) - } - } - dynamic "revoked_certificate" { - for_each = var.vpn.revoked_certificates - content { - name = revoked_certificate.value.name - thumbprint = revoked_certificate.value.thumbprint - } - } - vpn_auth_types = var.vpn.vpn_auth_types - } - } + dynamic "vpn_client_configuration" { + for_each = length(var.vpn.vpn_client_address_space) > 0 ? [1] : [] + content { + address_space = var.vpn.vpn_client_address_space + vpn_client_protocols = var.vpn.vpn_client_protocols + aad_tenant = var.vpn.vpn_client_aad_tenant + aad_audience = var.vpn.vpn_client_aad_audience + aad_issuer = var.vpn.vpn_client_aad_issuer + dynamic "root_certificate" { + for_each = var.vpn.root_certificates + content { + name = root_certificate.value.name + public_cert_data = coalesce( + root_certificate.value.public_cert_data, + root_certificate.value.public_cert + ) + } + } + dynamic "revoked_certificate" { + for_each = var.vpn.revoked_certificates + content { + name = revoked_certificate.value.name + thumbprint = revoked_certificate.value.thumbprint + } + } + vpn_auth_types = var.vpn.vpn_auth_types + } + } - dynamic "bgp_settings" { - for_each = var.vpn.bgp_settings != null ? [1] : [] - content { - asn = var.vpn.bgp_settings.asn - peer_weight = var.vpn.bgp_settings.peer_weight - dynamic "peering_addresses" { - for_each = try(var.vpn.bgp_settings.peering_addresses, []) - content { - ip_configuration_name = peering_addresses.value.ip_configuration_name - apipa_addresses = peering_addresses.value.apipa_addresses - } - } - } - } + dynamic "bgp_settings" { + for_each = var.vpn.bgp_settings != null ? [1] : [] + content { + asn = var.vpn.bgp_settings.asn + peer_weight = var.vpn.bgp_settings.peer_weight + dynamic "peering_addresses" { + for_each = try(var.vpn.bgp_settings.peering_addresses, []) + content { + ip_configuration_name = peering_addresses.value.ip_configuration_name + apipa_addresses = peering_addresses.value.apipa_addresses + } + } + } + } - dynamic "timeouts" { - for_each = var.vpn.timeouts != null ? [1] : [] - content { - create = var.vpn.timeouts.create - read = var.vpn.timeouts.read - update = var.vpn.timeouts.update - delete = var.vpn.timeouts.delete - } - } + dynamic "timeouts" { + for_each = var.vpn.timeouts != null ? [1] : [] + content { + create = var.vpn.timeouts.create + read = var.vpn.timeouts.read + update = var.vpn.timeouts.update + delete = var.vpn.timeouts.delete + } + } } diff --git a/modules/azure-vnet-gateway/variables.tf b/modules/azure-vnet-gateway/variables.tf index 1ad6c6251..c338a9198 100644 --- a/modules/azure-vnet-gateway/variables.tf +++ b/modules/azure-vnet-gateway/variables.tf @@ -1,31 +1,32 @@ ## VARIABLES SECTION + variable "vpn" { description = "VPN Gateway configuration object (includes P2S config)" type = object({ - vnet_name = string - gateway_subnet_name = string - location = string - resource_group_name = string - gateway_name = string - ip_name = string - public_ip_name = string - public_ip_id = optional(string) - ip_allocation_method = string - gateway_subnet_id = optional(string) - type = string - vpn_type = string - active_active = bool - enable_bgp = bool - sku = string - generation = optional(string) - default_local_network_gateway_id = optional(string) - edge_zone = optional(string) - private_ip_address_enabled = optional(bool) + vnet_name = string + gateway_subnet_name = string + location = string + resource_group_name = string + gateway_name = string + ip_name = string + public_ip_name = string + public_ip_id = optional(string) + ip_allocation_method = string + gateway_subnet_id = optional(string) + type = string + vpn_type = string + active_active = bool + enable_bgp = bool + sku = string + generation = optional(string) + default_local_network_gateway_id = optional(string) + edge_zone = optional(string) + private_ip_address_enabled = optional(bool) bgp_route_translation_for_nat_enabled = optional(bool) - dns_forwarding_enabled = optional(bool) - ip_sec_replay_protection_enabled = optional(bool) - remote_vnet_traffic_enabled = optional(bool) - virtual_wan_traffic_enabled = optional(bool) + dns_forwarding_enabled = optional(bool) + ip_sec_replay_protection_enabled = optional(bool) + remote_vnet_traffic_enabled = optional(bool) + virtual_wan_traffic_enabled = optional(bool) # ip_configuration block fields private_ip_address_allocation = optional(string) @@ -39,24 +40,24 @@ variable "vpn" { vpn_client_aad_tenant = optional(string) vpn_client_aad_audience = optional(string) vpn_client_aad_issuer = optional(string) - root_certificates = optional(list(object({ - name = string - public_cert = optional(string) + root_certificates = optional(list(object({ + name = string + public_cert = optional(string) public_cert_data = optional(string) })), []) - revoked_certificates = optional(list(object({ + revoked_certificates = optional(list(object({ name = string thumbprint = string })), []) - vpn_auth_types = optional(list(string), []) + vpn_auth_types = optional(list(string), []) # bgp_settings block bgp_settings = optional(object({ - asn = optional(number) - peer_weight = optional(number) + asn = optional(number) + peer_weight = optional(number) peering_addresses = optional(list(object({ ip_configuration_name = optional(string) - apipa_addresses = optional(list(string)) + apipa_addresses = optional(list(string)) })), []) })) diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf index 37d9e3949..5cb323944 100644 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ b/modules/azure-vnet-gateway/vpn_nat_rule.tf @@ -2,13 +2,13 @@ # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_nat_rule resource "azurerm_virtual_network_gateway_nat_rule" "this" { - for_each = { for idx, rule in var.nat_rules : idx => rule } + for_each = { for idx, rule in var.nat_rules : idx => rule } name = each.value.name resource_group_name = var.vpn.resource_group_name virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id mode = each.value.mode type = each.value.type - ip_configuration_id = coalesce( + ip_configuration_id = coalesce( try(each.value.ip_configuration_id, null), data.azurerm_virtual_network_gateway.this.ip_configuration[0].id ) From 9a87f168969d6bdc57a04c0f8b8b3afb2fad12bf Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 16:30:31 +0100 Subject: [PATCH 51/54] fix: claims vnetgateway, localnetgateway, connection Signed-off-by: jcframil --- modules/azure-localnet-gateway/README.md | 88 +++++++++++++ .../.terraform-docs.yml | 48 +++++++ .../azure-vnet-gateway-connection/README.md | 121 ++++++++++++++++++ modules/azure-vnet-gateway/README.md | 99 ++++++++++++++ 4 files changed, 356 insertions(+) create mode 100644 modules/azure-localnet-gateway/README.md create mode 100644 modules/azure-vnet-gateway-connection/.terraform-docs.yml create mode 100644 modules/azure-vnet-gateway-connection/README.md create mode 100644 modules/azure-vnet-gateway/README.md diff --git a/modules/azure-localnet-gateway/README.md b/modules/azure-localnet-gateway/README.md new file mode 100644 index 000000000..f62def968 --- /dev/null +++ b/modules/azure-localnet-gateway/README.md @@ -0,0 +1,88 @@ + +# **Azure Local Network Gateway Terraform Module** + +## Overview + +This module provisions and manages Azure Local Network Gateways for Site-to-Site VPN connections using the [azurerm\_local\_network\_gateway](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway) resource. It is suitable for production, staging, and development environments, y puede integrarse en proyectos Terraform más grandes o usarse de forma independiente. + +## Key Features + +- **Multiple Gateway Support**: Create one or more Azure Local Network Gateways with flexible configuration. +- **Custom Address Spaces**: Define custom address spaces and gateway IPs for each local network. +- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. +- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. + +## Basic Usage + +See the main README and the `_examples/` directory for usage examples. + +```hcl +module "localnet_gateway" { + source = "./modules/azure-localnet-gateway" + localnet = [ + { + local_gateway_name = "example-gateway" + location = "westeurope" + resource_group_name = "example-rg" + local_gateway_ip = "203.0.113.1" + local_gateway_address_space = ["10.1.0.0/16"] + tags_from_rg = true + tags = { + environment = "dev" + } + } + ] +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.7.0 | +| [azurerm](#requirement\_azurerm) | 4.58.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | 4.58.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_local_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/local_network_gateway) | resource | +| [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/resource_group) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [localnet](#input\_localnet) | List of local network gateway objects |
list(object({
local_gateway_name = string
location = string
resource_group_name = string
local_gateway_ip = string
local_gateway_address_space = list(string)
tags_from_rg = optional(bool)
tags = optional(map(string))
}))
| `[]` | no | + +## Outputs + +No outputs. + +## Examples + +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples): + +- [basic\_localnet](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples/basic\_localnet) - Basic local network gateway example. +- [multiple\_address\_spaces](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples/multiple\_address\_spaces) - Example with multiple address spaces. +- [with\_tags\_from\_rg](https://github.com/prefapp/tfm/tree/main/modules/azure-localnet-gateway/_examples/with\_tags\_from\_rg) - Example inheriting tags from the resource group. + +## Remote resources + +- **Azure Local Network Gateway**: [azurerm\_local\_network\_gateway documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/local_network_gateway) +- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + +## Support + +For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). + \ No newline at end of file diff --git a/modules/azure-vnet-gateway-connection/.terraform-docs.yml b/modules/azure-vnet-gateway-connection/.terraform-docs.yml new file mode 100644 index 000000000..3a69365ff --- /dev/null +++ b/modules/azure-vnet-gateway-connection/.terraform-docs.yml @@ -0,0 +1,48 @@ +formatter: "markdown" + +version: "" + +header-from: docs/header.md +footer-from: docs/footer.md + +recursive: + enabled: false + path: modules + include-main: true + +sections: + hide: [] + show: [] + +content: "" + +output: + file: "README.md" + mode: inject + template: |- + + {{ .Content }} + + +output-values: + enabled: false + from: "" + +sort: + enabled: true + by: name + +settings: + anchor: true + color: true + default: true + description: false + escape: true + hide-empty: false + html: true + indent: 2 + lockfile: true + read-comments: true + required: true + sensitive: true + type: true diff --git a/modules/azure-vnet-gateway-connection/README.md b/modules/azure-vnet-gateway-connection/README.md new file mode 100644 index 000000000..be7ab5d35 --- /dev/null +++ b/modules/azure-vnet-gateway-connection/README.md @@ -0,0 +1,121 @@ + +# **Azure Virtual Network Gateway Connection Terraform Module** + +## Overview + +This module provisions and manages Azure Virtual Network Gateway Connections for Site-to-Site (S2S), VNet-to-VNet, and ExpressRoute VPNs. It supports advanced configuration, including custom IPsec/IKE policies, NAT rules, BGP, and shared key management via Azure Key Vault. + +It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. + +## Key Features + +- **S2S, VNet-to-VNet, and ExpressRoute Support**: Create connections between Azure VNets, on-premises networks, or ExpressRoute circuits. +- **Custom IPsec/IKE Policies**: Fine-grained control over encryption, integrity, and key exchange settings. +- **NAT Rule Integration**: Attach ingress and egress NAT rules to connections. +- **Key Vault Integration**: Securely manage shared keys using Azure Key Vault. +- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. +- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. + +## Basic Usage + +See the main README and the `_examples/` directory for usage examples. + +```hcl +module "vnet_gateway_connection" { + source = "./modules/azure-vnet-gateway-connection" + connection = [{ + name = "example-connection" + location = "westeurope" + resource_group_name = "example-rg" + gateway_name = "example-vnet-gw" + local_gateway_name = "example-local-gw" + local_gateway_resource_group_name = "example-local-rg" + keyvault_vault_name = "example-kv" + keyvault_vault_rg = "example-kv-rg" + keyvault_secret_name = "vpn-shared-key" + type = "IPsec" + connection_mode = "InitiatorOnly" + connection_protocol = "IKEv2" + enable_bgp = false + express_route_gateway_bypass = false + dpd_timeout_seconds = 30 + routing_weight = 0 + use_policy_based_traffic_selectors = false + ipsec_policy = { + dh_group = "DHGroup14" + ike_encryption = "AES256" + ike_integrity = "SHA256" + ipsec_encryption = "AES256" + ipsec_integrity = "SHA256" + pfs_group = "PFS2" + sa_datasize = 0 + sa_lifetime = 28800 + } + egress_nat_rule_ids = [] + ingress_nat_rule_ids = [] + local_azure_ip_address_enabled = false + tags_from_rg = true + tags = { + environment = "dev" + application = "example-app" + } + }] +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.7.0 | +| [azurerm](#requirement\_azurerm) | 4.58.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | 4.58.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_virtual_network_gateway_connection.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/virtual_network_gateway_connection) | resource | +| [azurerm_key_vault.s2s](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/key_vault) | data source | +| [azurerm_key_vault_secret.s2s](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/key_vault_secret) | data source | +| [azurerm_local_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/local_network_gateway) | data source | +| [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/resource_group) | data source | +| [azurerm_virtual_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/virtual_network_gateway) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [connection](#input\_connection) | List of Site-to-Site VPN connection objects |
list(object({
name = string
location = string
resource_group_name = string
local_gateway_name = string
local_gateway_resource_group_name = string
type = string
gateway_name = string
shared_key = optional(string)
keyvault_secret_name = optional(string)
keyvault_vault_name = optional(string)
keyvault_vault_rg = optional(string)
virtual_network_gateway_id = optional(string)
local_network_gateway_id = optional(string)
connection_protocol = optional(string)
routing_weight = optional(number)
authorization_key = optional(string)
express_route_circuit_id = optional(string)
peer_virtual_network_gateway_id = optional(string)
use_policy_based_traffic_selectors = optional(bool)
express_route_gateway_bypass = optional(bool)
dpd_timeout_seconds = optional(number)
connection_mode = optional(string)
tags_from_rg = optional(bool)
egress_nat_rule_ids = optional(list(string))
ingress_nat_rule_ids = optional(list(string))
local_azure_ip_address_enabled = optional(bool)
tags = optional(map(string))
ipsec_policy = optional(object({
dh_group = string
ike_encryption = string
ike_integrity = string
ipsec_encryption = string
ipsec_integrity = string
pfs_group = string
sa_lifetime = number
sa_datasize = number
}))
}))
| `[]` | no | + +## Outputs + +No outputs. + +## Examples + +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples): + +- [s2s\_basic](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/s2s\_basic) - Basic Site-to-Site connection example. +- [with\_nat\_rules](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with\_nat\_rules) - Example with ingress/egress NAT rules. +- [with\_keyvault](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with\_keyvault) - Example using Azure Key Vault for shared key management. + +## Remote resources + +- **Azure Virtual Network Gateway Connection**: [azurerm\_virtual\_network\_gateway\_connection documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection) +- **Azure Key Vault Secret**: [azurerm\_key\_vault\_secret documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) +- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + +## Support + +For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). + \ No newline at end of file diff --git a/modules/azure-vnet-gateway/README.md b/modules/azure-vnet-gateway/README.md new file mode 100644 index 000000000..a0f4126be --- /dev/null +++ b/modules/azure-vnet-gateway/README.md @@ -0,0 +1,99 @@ + +# **Azure Virtual Network Gateway Terraform Module** + +## Overview + +This module provisions and manages an Azure Virtual Network Gateway for VPN connectivity, supporting both Route-based and Policy-based configurations. It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. + +## Key Features + +- **Flexible Gateway Deployment**: Supports Route-based and Policy-based VPN gateways, active-active mode, and multiple SKUs. +- **Custom IP Configuration**: Allows custom public IP, subnet, and private IP allocation. +- **Advanced VPN Client Support**: Configure VPN client address spaces, protocols, and AAD integration for P2S. +- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. +- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. + +## Basic Usage + +See the main README and the `_examples/` directory for usage examples. + +```hcl +module "vnet_gateway" { + source = "./modules/azure-vnet-gateway" + vpn = { + vnet_name = "my-vnet" + gateway_subnet_name = "GatewaySubnet" + location = "westeurope" + resource_group_name = "my-rg" + gateway_name = "my-vpn-gw" + ip_name = "my-vpn-ip" + public_ip_name = "my-vpn-public-ip" + ip_allocation_method = "Dynamic" + type = "Vpn" + vpn_type = "RouteBased" + active_active = false + enable_bgp = false + sku = "VpnGw1" + # ...other optional fields... + } +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.7.0 | +| [azurerm](#requirement\_azurerm) | 4.58.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | 4.58.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_virtual_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/virtual_network_gateway) | resource | +| [azurerm_virtual_network_gateway_nat_rule.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/virtual_network_gateway_nat_rule) | resource | +| [azurerm_public_ip.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/public_ip) | data source | +| [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/resource_group) | data source | +| [azurerm_subnet.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/subnet) | data source | +| [azurerm_virtual_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/virtual_network_gateway) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [nat\_rules](#input\_nat\_rules) | List of NAT rules for the VPN gateway |
list(object({
name = string
mode = string
type = string
ip_configuration_id = optional(string)
external_mapping_address_space = string
internal_mapping_address_space = string
}))
| `[]` | no | +| [tags](#input\_tags) | Tags to apply to resources | `map(string)` | `{}` | no | +| [tags\_from\_rg](#input\_tags\_from\_rg) | Use resource group tags as base for module tags | `bool` | `false` | no | +| [vpn](#input\_vpn) | VPN Gateway configuration object (includes P2S config) |
object({
vnet_name = string
gateway_subnet_name = string
location = string
resource_group_name = string
gateway_name = string
ip_name = string
public_ip_name = string
public_ip_id = optional(string)
ip_allocation_method = string
gateway_subnet_id = optional(string)
type = string
vpn_type = string
active_active = bool
enable_bgp = bool
sku = string
generation = optional(string)
default_local_network_gateway_id = optional(string)
edge_zone = optional(string)
private_ip_address_enabled = optional(bool)
bgp_route_translation_for_nat_enabled = optional(bool)
dns_forwarding_enabled = optional(bool)
ip_sec_replay_protection_enabled = optional(bool)
remote_vnet_traffic_enabled = optional(bool)
virtual_wan_traffic_enabled = optional(bool)

# ip_configuration block fields
private_ip_address_allocation = optional(string)

# custom_route block
custom_route_address_prefixes = optional(list(string), [])

# vpn_client_configuration block
vpn_client_address_space = optional(list(string), [])
vpn_client_protocols = optional(list(string), [])
vpn_client_aad_tenant = optional(string)
vpn_client_aad_audience = optional(string)
vpn_client_aad_issuer = optional(string)
root_certificates = optional(list(object({
name = string
public_cert = optional(string)
public_cert_data = optional(string)
})), [])
revoked_certificates = optional(list(object({
name = string
thumbprint = string
})), [])
vpn_auth_types = optional(list(string), [])

# bgp_settings block
bgp_settings = optional(object({
asn = optional(number)
peer_weight = optional(number)
peering_addresses = optional(list(object({
ip_configuration_name = optional(string)
apipa_addresses = optional(list(string))
})), [])
}))

# timeouts block
timeouts = optional(object({
create = optional(string)
read = optional(string)
update = optional(string)
delete = optional(string)
}))
})
| n/a | yes | + +## Outputs + +No outputs. + +## Examples + +For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples): + +- [basic\_route\_based](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/basic\_route\_based) - Basic RouteBased gateway example. +- [active\_active\_bgp](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/active\_active\_bgp) - Active-Active gateway with BGP enabled. +- [vpn\_client\_aad](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/vpn\_client\_aad) - Gateway with VPN Client and Azure AD authentication. + +## Remote resources + +- **Azure Virtual Network Gateway**: [azurerm\_virtual\_network\_gateway documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway) +- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + +## Support + +For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). + \ No newline at end of file From 29341e65c322421e5f6c67d703a817bc48dc057c Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 16:35:06 +0100 Subject: [PATCH 52/54] fix: tf format Signed-off-by: jcframil --- modules/azure-vnet-gateway-connection/docs/footer.md | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/azure-vnet-gateway-connection/docs/footer.md b/modules/azure-vnet-gateway-connection/docs/footer.md index 28e1ccacb..ae03a3fd1 100644 --- a/modules/azure-vnet-gateway-connection/docs/footer.md +++ b/modules/azure-vnet-gateway-connection/docs/footer.md @@ -1,4 +1,3 @@ - ## Examples For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples): From f6a652fb90a43bd8ba07a17136b9dd3f438efb92 Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 16:48:57 +0100 Subject: [PATCH 53/54] feat:azure-localnet-gateway splited module Signed-off-by: jcframil --- .../.terraform-docs.yml | 48 ------- .../azure-vnet-gateway-connection/README.md | 121 ------------------ .../_examples/s2s_basic/example.tf | 40 ------ .../_examples/s2s_basic/example.yaml | 34 ----- .../with_keyvault_shared_key/example.tf | 40 ------ .../with_keyvault_shared_key/example.yaml | 34 ----- .../_examples/with_nat_rules/example.tf | 40 ------ .../_examples/with_nat_rules/example.yaml | 36 ------ modules/azure-vnet-gateway-connection/data.tf | 35 ----- .../docs/footer.md | 17 --- .../docs/header.md | 63 --------- .../azure-vnet-gateway-connection/locals.tf | 12 -- modules/azure-vnet-gateway-connection/main.tf | 51 -------- .../variables.tf | 47 ------- .../azure-vnet-gateway-connection/versions.tf | 10 -- .../azure-vnet-gateway/.terraform-docs.yml | 48 ------- modules/azure-vnet-gateway/README.md | 99 -------------- .../_examples/active_active_bgp/example.tf | 20 --- .../_examples/active_active_bgp/example.yaml | 17 --- .../_examples/basic_route_based/example.tf | 19 --- .../_examples/basic_route_based/example.yaml | 16 --- .../_examples/vpn_client_aad/example.tf | 22 ---- .../_examples/vpn_client_aad/example.yaml | 22 ---- modules/azure-vnet-gateway/data.tf | 25 ---- modules/azure-vnet-gateway/docs/footer.md | 16 --- modules/azure-vnet-gateway/docs/header.md | 39 ------ modules/azure-vnet-gateway/locals.tf | 6 - modules/azure-vnet-gateway/main.tf | 88 ------------- modules/azure-vnet-gateway/variables.tf | 97 -------------- modules/azure-vnet-gateway/versions.tf | 10 -- modules/azure-vnet-gateway/vpn_nat_rule.tf | 23 ---- 31 files changed, 1195 deletions(-) delete mode 100644 modules/azure-vnet-gateway-connection/.terraform-docs.yml delete mode 100644 modules/azure-vnet-gateway-connection/README.md delete mode 100644 modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf delete mode 100644 modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml delete mode 100644 modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf delete mode 100644 modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml delete mode 100644 modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf delete mode 100644 modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml delete mode 100644 modules/azure-vnet-gateway-connection/data.tf delete mode 100644 modules/azure-vnet-gateway-connection/docs/footer.md delete mode 100644 modules/azure-vnet-gateway-connection/docs/header.md delete mode 100644 modules/azure-vnet-gateway-connection/locals.tf delete mode 100644 modules/azure-vnet-gateway-connection/main.tf delete mode 100644 modules/azure-vnet-gateway-connection/variables.tf delete mode 100644 modules/azure-vnet-gateway-connection/versions.tf delete mode 100644 modules/azure-vnet-gateway/.terraform-docs.yml delete mode 100644 modules/azure-vnet-gateway/README.md delete mode 100644 modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf delete mode 100644 modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml delete mode 100644 modules/azure-vnet-gateway/_examples/basic_route_based/example.tf delete mode 100644 modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml delete mode 100644 modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf delete mode 100644 modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml delete mode 100644 modules/azure-vnet-gateway/data.tf delete mode 100644 modules/azure-vnet-gateway/docs/footer.md delete mode 100644 modules/azure-vnet-gateway/docs/header.md delete mode 100644 modules/azure-vnet-gateway/locals.tf delete mode 100644 modules/azure-vnet-gateway/main.tf delete mode 100644 modules/azure-vnet-gateway/variables.tf delete mode 100644 modules/azure-vnet-gateway/versions.tf delete mode 100644 modules/azure-vnet-gateway/vpn_nat_rule.tf diff --git a/modules/azure-vnet-gateway-connection/.terraform-docs.yml b/modules/azure-vnet-gateway-connection/.terraform-docs.yml deleted file mode 100644 index 3a69365ff..000000000 --- a/modules/azure-vnet-gateway-connection/.terraform-docs.yml +++ /dev/null @@ -1,48 +0,0 @@ -formatter: "markdown" - -version: "" - -header-from: docs/header.md -footer-from: docs/footer.md - -recursive: - enabled: false - path: modules - include-main: true - -sections: - hide: [] - show: [] - -content: "" - -output: - file: "README.md" - mode: inject - template: |- - - {{ .Content }} - - -output-values: - enabled: false - from: "" - -sort: - enabled: true - by: name - -settings: - anchor: true - color: true - default: true - description: false - escape: true - hide-empty: false - html: true - indent: 2 - lockfile: true - read-comments: true - required: true - sensitive: true - type: true diff --git a/modules/azure-vnet-gateway-connection/README.md b/modules/azure-vnet-gateway-connection/README.md deleted file mode 100644 index be7ab5d35..000000000 --- a/modules/azure-vnet-gateway-connection/README.md +++ /dev/null @@ -1,121 +0,0 @@ - -# **Azure Virtual Network Gateway Connection Terraform Module** - -## Overview - -This module provisions and manages Azure Virtual Network Gateway Connections for Site-to-Site (S2S), VNet-to-VNet, and ExpressRoute VPNs. It supports advanced configuration, including custom IPsec/IKE policies, NAT rules, BGP, and shared key management via Azure Key Vault. - -It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. - -## Key Features - -- **S2S, VNet-to-VNet, and ExpressRoute Support**: Create connections between Azure VNets, on-premises networks, or ExpressRoute circuits. -- **Custom IPsec/IKE Policies**: Fine-grained control over encryption, integrity, and key exchange settings. -- **NAT Rule Integration**: Attach ingress and egress NAT rules to connections. -- **Key Vault Integration**: Securely manage shared keys using Azure Key Vault. -- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. -- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. - -## Basic Usage - -See the main README and the `_examples/` directory for usage examples. - -```hcl -module "vnet_gateway_connection" { - source = "./modules/azure-vnet-gateway-connection" - connection = [{ - name = "example-connection" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vnet-gw" - local_gateway_name = "example-local-gw" - local_gateway_resource_group_name = "example-local-rg" - keyvault_vault_name = "example-kv" - keyvault_vault_rg = "example-kv-rg" - keyvault_secret_name = "vpn-shared-key" - type = "IPsec" - connection_mode = "InitiatorOnly" - connection_protocol = "IKEv2" - enable_bgp = false - express_route_gateway_bypass = false - dpd_timeout_seconds = 30 - routing_weight = 0 - use_policy_based_traffic_selectors = false - ipsec_policy = { - dh_group = "DHGroup14" - ike_encryption = "AES256" - ike_integrity = "SHA256" - ipsec_encryption = "AES256" - ipsec_integrity = "SHA256" - pfs_group = "PFS2" - sa_datasize = 0 - sa_lifetime = 28800 - } - egress_nat_rule_ids = [] - ingress_nat_rule_ids = [] - local_azure_ip_address_enabled = false - tags_from_rg = true - tags = { - environment = "dev" - application = "example-app" - } - }] -} -``` - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.7.0 | -| [azurerm](#requirement\_azurerm) | 4.58.0 | - -## Providers - -| Name | Version | -|------|---------| -| [azurerm](#provider\_azurerm) | 4.58.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [azurerm_virtual_network_gateway_connection.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/virtual_network_gateway_connection) | resource | -| [azurerm_key_vault.s2s](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/key_vault) | data source | -| [azurerm_key_vault_secret.s2s](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/key_vault_secret) | data source | -| [azurerm_local_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/local_network_gateway) | data source | -| [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/resource_group) | data source | -| [azurerm_virtual_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/virtual_network_gateway) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [connection](#input\_connection) | List of Site-to-Site VPN connection objects |
list(object({
name = string
location = string
resource_group_name = string
local_gateway_name = string
local_gateway_resource_group_name = string
type = string
gateway_name = string
shared_key = optional(string)
keyvault_secret_name = optional(string)
keyvault_vault_name = optional(string)
keyvault_vault_rg = optional(string)
virtual_network_gateway_id = optional(string)
local_network_gateway_id = optional(string)
connection_protocol = optional(string)
routing_weight = optional(number)
authorization_key = optional(string)
express_route_circuit_id = optional(string)
peer_virtual_network_gateway_id = optional(string)
use_policy_based_traffic_selectors = optional(bool)
express_route_gateway_bypass = optional(bool)
dpd_timeout_seconds = optional(number)
connection_mode = optional(string)
tags_from_rg = optional(bool)
egress_nat_rule_ids = optional(list(string))
ingress_nat_rule_ids = optional(list(string))
local_azure_ip_address_enabled = optional(bool)
tags = optional(map(string))
ipsec_policy = optional(object({
dh_group = string
ike_encryption = string
ike_integrity = string
ipsec_encryption = string
ipsec_integrity = string
pfs_group = string
sa_lifetime = number
sa_datasize = number
}))
}))
| `[]` | no | - -## Outputs - -No outputs. - -## Examples - -For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples): - -- [s2s\_basic](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/s2s\_basic) - Basic Site-to-Site connection example. -- [with\_nat\_rules](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with\_nat\_rules) - Example with ingress/egress NAT rules. -- [with\_keyvault](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with\_keyvault) - Example using Azure Key Vault for shared key management. - -## Remote resources - -- **Azure Virtual Network Gateway Connection**: [azurerm\_virtual\_network\_gateway\_connection documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection) -- **Azure Key Vault Secret**: [azurerm\_key\_vault\_secret documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) -- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) - -## Support - -For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). - \ No newline at end of file diff --git a/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf b/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf deleted file mode 100644 index 92c2f1f36..000000000 --- a/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.tf +++ /dev/null @@ -1,40 +0,0 @@ -module "vnet_gateway_connection" { - source = "../../" - connection = [{ - name = "example-connection" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vnet-gw" - local_gateway_name = "example-local-gw" - local_gateway_resource_group_name = "example-local-rg" - keyvault_vault_name = "example-kv" - keyvault_vault_rg = "example-kv-rg" - keyvault_secret_name = "vpn-shared-key" - type = "IPsec" - connection_mode = "InitiatorOnly" - connection_protocol = "IKEv2" - enable_bgp = false - express_route_gateway_bypass = false - dpd_timeout_seconds = 30 - routing_weight = 0 - use_policy_based_traffic_selectors = false - ipsec_policy = { - dh_group = "DHGroup14" - ike_encryption = "AES256" - ike_integrity = "SHA256" - ipsec_encryption = "AES256" - ipsec_integrity = "SHA256" - pfs_group = "PFS2" - sa_datasize = 0 - sa_lifetime = 28800 - } - egress_nat_rule_ids = [] - ingress_nat_rule_ids = [] - local_azure_ip_address_enabled = false - tags_from_rg = true - tags = { - environment = "dev" - application = "example-app" - } - }] -} diff --git a/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml b/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml deleted file mode 100644 index a52958dad..000000000 --- a/modules/azure-vnet-gateway-connection/_examples/s2s_basic/example.yaml +++ /dev/null @@ -1,34 +0,0 @@ -connection: - - name: example-connection - location: westeurope - resource_group_name: example-rg - gateway_name: example-vnet-gw - local_gateway_name: example-local-gw - local_gateway_resource_group_name: example-local-rg - keyvault_vault_name: example-kv - keyvault_vault_rg: example-kv-rg - keyvault_secret_name: vpn-shared-key - type: IPsec - connection_mode: InitiatorOnly - connection_protocol: IKEv2 - enable_bgp: false - express_route_gateway_bypass: false - dpd_timeout_seconds: 30 - routing_weight: 0 - use_policy_based_traffic_selectors: false - ipsec_policy: - dh_group: DHGroup14 - ike_encryption: AES256 - ike_integrity: SHA256 - ipsec_encryption: AES256 - ipsec_integrity: SHA256 - pfs_group: PFS2 - sa_datasize: 0 - sa_lifetime: 28800 - egress_nat_rule_ids: [] - ingress_nat_rule_ids: [] - local_azure_ip_address_enabled: false - tags_from_rg: true - tags: - environment: dev - application: example-app diff --git a/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf b/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf deleted file mode 100644 index bf739db15..000000000 --- a/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.tf +++ /dev/null @@ -1,40 +0,0 @@ -module "vnet_gateway_connection" { - source = "../../" - connection = [{ - name = "keyvault-connection" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vnet-gw" - local_gateway_name = "example-local-gw" - local_gateway_resource_group_name = "example-local-rg" - keyvault_vault_name = "example-kv" - keyvault_vault_rg = "example-kv-rg" - keyvault_secret_name = "vpn-shared-key" - type = "IPsec" - connection_mode = "InitiatorOnly" - connection_protocol = "IKEv2" - enable_bgp = false - express_route_gateway_bypass = false - dpd_timeout_seconds = 30 - routing_weight = 0 - use_policy_based_traffic_selectors = false - ipsec_policy = { - dh_group = "DHGroup14" - ike_encryption = "AES256" - ike_integrity = "SHA256" - ipsec_encryption = "AES256" - ipsec_integrity = "SHA256" - pfs_group = "PFS2" - sa_datasize = 0 - sa_lifetime = 28800 - } - egress_nat_rule_ids = [] - ingress_nat_rule_ids = [] - local_azure_ip_address_enabled = false - tags_from_rg = true - tags = { - environment = "prod" - application = "keyvault-app" - } - }] -} diff --git a/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml b/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml deleted file mode 100644 index abe5f4694..000000000 --- a/modules/azure-vnet-gateway-connection/_examples/with_keyvault_shared_key/example.yaml +++ /dev/null @@ -1,34 +0,0 @@ -connection: - - name: keyvault-connection - location: westeurope - resource_group_name: example-rg - gateway_name: example-vnet-gw - local_gateway_name: example-local-gw - local_gateway_resource_group_name: example-local-rg - keyvault_vault_name: example-kv - keyvault_vault_rg: example-kv-rg - keyvault_secret_name: vpn-shared-key - type: IPsec - connection_mode: InitiatorOnly - connection_protocol: IKEv2 - enable_bgp: false - express_route_gateway_bypass: false - dpd_timeout_seconds: 30 - routing_weight: 0 - use_policy_based_traffic_selectors: false - ipsec_policy: - dh_group: DHGroup14 - ike_encryption: AES256 - ike_integrity: SHA256 - ipsec_encryption: AES256 - ipsec_integrity: SHA256 - pfs_group: PFS2 - sa_datasize: 0 - sa_lifetime: 28800 - egress_nat_rule_ids: [] - ingress_nat_rule_ids: [] - local_azure_ip_address_enabled: false - tags_from_rg: true - tags: - environment: prod - application: keyvault-app diff --git a/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf b/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf deleted file mode 100644 index 003d456d7..000000000 --- a/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.tf +++ /dev/null @@ -1,40 +0,0 @@ -module "vnet_gateway_connection" { - source = "../../" - connection = [{ - name = "nat-connection" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vnet-gw" - local_gateway_name = "example-local-gw" - local_gateway_resource_group_name = "example-local-rg" - keyvault_vault_name = "example-kv" - keyvault_vault_rg = "example-kv-rg" - keyvault_secret_name = "vpn-shared-key" - type = "IPsec" - connection_mode = "InitiatorOnly" - connection_protocol = "IKEv2" - enable_bgp = false - express_route_gateway_bypass = false - dpd_timeout_seconds = 30 - routing_weight = 0 - use_policy_based_traffic_selectors = false - ipsec_policy = { - dh_group = "DHGroup14" - ike_encryption = "AES256" - ike_integrity = "SHA256" - ipsec_encryption = "AES256" - ipsec_integrity = "SHA256" - pfs_group = "PFS2" - sa_datasize = 0 - sa_lifetime = 28800 - } - egress_nat_rule_ids = ["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/egress_nat"] - ingress_nat_rule_ids = ["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/ingress_nat"] - local_azure_ip_address_enabled = false - tags_from_rg = false - tags = { - environment = "test" - application = "nat-app" - } - }] -} diff --git a/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml b/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml deleted file mode 100644 index 7b372f0dd..000000000 --- a/modules/azure-vnet-gateway-connection/_examples/with_nat_rules/example.yaml +++ /dev/null @@ -1,36 +0,0 @@ -connection: - - name: nat-connection - location: westeurope - resource_group_name: example-rg - gateway_name: example-vnet-gw - local_gateway_name: example-local-gw - local_gateway_resource_group_name: example-local-rg - keyvault_vault_name: example-kv - keyvault_vault_rg: example-kv-rg - keyvault_secret_name: vpn-shared-key - type: IPsec - connection_mode: InitiatorOnly - connection_protocol: IKEv2 - enable_bgp: false - express_route_gateway_bypass: false - dpd_timeout_seconds: 30 - routing_weight: 0 - use_policy_based_traffic_selectors: false - ipsec_policy: - dh_group: DHGroup14 - ike_encryption: AES256 - ike_integrity: SHA256 - ipsec_encryption: AES256 - ipsec_integrity: SHA256 - pfs_group: PFS2 - sa_datasize: 0 - sa_lifetime: 28800 - egress_nat_rule_ids: - - /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/egress_nat - ingress_nat_rule_ids: - - /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/virtualNetworkGateways/example-vnet-gw/natRules/ingress_nat - local_azure_ip_address_enabled: false - tags_from_rg: false - tags: - environment: test - application: nat-app diff --git a/modules/azure-vnet-gateway-connection/data.tf b/modules/azure-vnet-gateway-connection/data.tf deleted file mode 100644 index cc555cd97..000000000 --- a/modules/azure-vnet-gateway-connection/data.tf +++ /dev/null @@ -1,35 +0,0 @@ -## DATA SOURCES SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group -data "azurerm_local_network_gateway" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.local_gateway_name - resource_group_name = each.value.local_gateway_resource_group_name -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network_gateway -data "azurerm_resource_group" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.resource_group_name -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network_gateway -data "azurerm_virtual_network_gateway" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.gateway_name - resource_group_name = each.value.resource_group_name -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret -data "azurerm_key_vault_secret" "s2s" { - for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_secret_name, null) != null && try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_secret_name - key_vault_id = data.azurerm_key_vault.s2s[each.key].id -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault -data "azurerm_key_vault" "s2s" { - for_each = { for idx, s in var.connection : idx => s if try(s.keyvault_vault_name, null) != null && try(s.keyvault_vault_rg, null) != null } - name = each.value.keyvault_vault_name - resource_group_name = each.value.keyvault_vault_rg -} diff --git a/modules/azure-vnet-gateway-connection/docs/footer.md b/modules/azure-vnet-gateway-connection/docs/footer.md deleted file mode 100644 index ae03a3fd1..000000000 --- a/modules/azure-vnet-gateway-connection/docs/footer.md +++ /dev/null @@ -1,17 +0,0 @@ -## Examples - -For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples): - -- [s2s_basic](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/s2s_basic) - Basic Site-to-Site connection example. -- [with_nat_rules](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with_nat_rules) - Example with ingress/egress NAT rules. -- [with_keyvault](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway-connection/_examples/with_keyvault) - Example using Azure Key Vault for shared key management. - -## Remote resources - -- **Azure Virtual Network Gateway Connection**: [azurerm_virtual_network_gateway_connection documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection) -- **Azure Key Vault Secret**: [azurerm_key_vault_secret documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) -- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) - -## Support - -For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). diff --git a/modules/azure-vnet-gateway-connection/docs/header.md b/modules/azure-vnet-gateway-connection/docs/header.md deleted file mode 100644 index 49162221f..000000000 --- a/modules/azure-vnet-gateway-connection/docs/header.md +++ /dev/null @@ -1,63 +0,0 @@ -# **Azure Virtual Network Gateway Connection Terraform Module** - -## Overview - -This module provisions and manages Azure Virtual Network Gateway Connections for Site-to-Site (S2S), VNet-to-VNet, and ExpressRoute VPNs. It supports advanced configuration, including custom IPsec/IKE policies, NAT rules, BGP, and shared key management via Azure Key Vault. - -It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. - -## Key Features - -- **S2S, VNet-to-VNet, and ExpressRoute Support**: Create connections between Azure VNets, on-premises networks, or ExpressRoute circuits. -- **Custom IPsec/IKE Policies**: Fine-grained control over encryption, integrity, and key exchange settings. -- **NAT Rule Integration**: Attach ingress and egress NAT rules to connections. -- **Key Vault Integration**: Securely manage shared keys using Azure Key Vault. -- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. -- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. - -## Basic Usage - -See the main README and the `_examples/` directory for usage examples. - -```hcl -module "vnet_gateway_connection" { - source = "./modules/azure-vnet-gateway-connection" - connection = [{ - name = "example-connection" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vnet-gw" - local_gateway_name = "example-local-gw" - local_gateway_resource_group_name = "example-local-rg" - keyvault_vault_name = "example-kv" - keyvault_vault_rg = "example-kv-rg" - keyvault_secret_name = "vpn-shared-key" - type = "IPsec" - connection_mode = "InitiatorOnly" - connection_protocol = "IKEv2" - enable_bgp = false - express_route_gateway_bypass = false - dpd_timeout_seconds = 30 - routing_weight = 0 - use_policy_based_traffic_selectors = false - ipsec_policy = { - dh_group = "DHGroup14" - ike_encryption = "AES256" - ike_integrity = "SHA256" - ipsec_encryption = "AES256" - ipsec_integrity = "SHA256" - pfs_group = "PFS2" - sa_datasize = 0 - sa_lifetime = 28800 - } - egress_nat_rule_ids = [] - ingress_nat_rule_ids = [] - local_azure_ip_address_enabled = false - tags_from_rg = true - tags = { - environment = "dev" - application = "example-app" - } - }] -} -``` diff --git a/modules/azure-vnet-gateway-connection/locals.tf b/modules/azure-vnet-gateway-connection/locals.tf deleted file mode 100644 index 4540baa34..000000000 --- a/modules/azure-vnet-gateway-connection/locals.tf +++ /dev/null @@ -1,12 +0,0 @@ -## LOCALS SECTION - -locals { - # Handle tags based on whether to use resource group tags or module-defined tags for each connection (key = idx) - tags = { for idx, s in var.connection : - idx => ( - coalesce(s.tags_from_rg, false) - ? merge(try(data.azurerm_resource_group.this[idx].tags, {}), try(s.tags, {})) - : try(s.tags, {}) - ) - } -} diff --git a/modules/azure-vnet-gateway-connection/main.tf b/modules/azure-vnet-gateway-connection/main.tf deleted file mode 100644 index 628e22256..000000000 --- a/modules/azure-vnet-gateway-connection/main.tf +++ /dev/null @@ -1,51 +0,0 @@ -## VPN CONNECTION SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_connection -resource "azurerm_virtual_network_gateway_connection" "this" { - for_each = { for idx, s in var.connection : idx => s } - name = each.value.name - location = each.value.location - resource_group_name = each.value.resource_group_name - egress_nat_rule_ids = try(each.value.egress_nat_rule_ids, null) - ingress_nat_rule_ids = try(each.value.ingress_nat_rule_ids, null) - local_azure_ip_address_enabled = try(each.value.local_azure_ip_address_enabled, null) - tags = local.tags[each.key] - type = each.value.type - virtual_network_gateway_id = ( - try(each.value.virtual_network_gateway_id, null) != null ? each.value.virtual_network_gateway_id : data.azurerm_virtual_network_gateway.this[each.key].id - ) - local_network_gateway_id = ( - try(each.value.local_network_gateway_id, null) != null ? each.value.local_network_gateway_id : data.azurerm_local_network_gateway.this[each.key].id - ) - shared_key = ( - try(each.value.shared_key, null) != null ? each.value.shared_key : ( - try(data.azurerm_key_vault_secret.s2s[each.key].value, null) != null ? data.azurerm_key_vault_secret.s2s[each.key].value : null - ) - ) - enable_bgp = try(each.value.enable_bgp, null) - connection_protocol = try(each.value.connection_protocol, null) - routing_weight = try(each.value.routing_weight, null) - authorization_key = try(each.value.authorization_key, null) - express_route_circuit_id = try(each.value.express_route_circuit_id, null) - peer_virtual_network_gateway_id = try(each.value.peer_virtual_network_gateway_id, null) - use_policy_based_traffic_selectors = try(each.value.use_policy_based_traffic_selectors, null) - express_route_gateway_bypass = try(each.value.express_route_gateway_bypass, null) - dpd_timeout_seconds = try(each.value.dpd_timeout_seconds, null) - connection_mode = try(each.value.connection_mode, null) - dynamic "ipsec_policy" { - for_each = try(each.value.ipsec_policy != null, false) ? [each.value.ipsec_policy] : [] - content { - dh_group = ipsec_policy.value.dh_group - ike_encryption = ipsec_policy.value.ike_encryption - ike_integrity = ipsec_policy.value.ike_integrity - ipsec_encryption = ipsec_policy.value.ipsec_encryption - ipsec_integrity = ipsec_policy.value.ipsec_integrity - pfs_group = ipsec_policy.value.pfs_group - sa_lifetime = ipsec_policy.value.sa_lifetime - sa_datasize = ipsec_policy.value.sa_datasize - } - } - lifecycle { - ignore_changes = [shared_key] - } -} diff --git a/modules/azure-vnet-gateway-connection/variables.tf b/modules/azure-vnet-gateway-connection/variables.tf deleted file mode 100644 index aae452cc0..000000000 --- a/modules/azure-vnet-gateway-connection/variables.tf +++ /dev/null @@ -1,47 +0,0 @@ -## VARIABLES SECTION - -variable "connection" { - description = "List of Site-to-Site VPN connection objects" - type = list(object({ - name = string - location = string - resource_group_name = string - local_gateway_name = string - local_gateway_resource_group_name = string - type = string - gateway_name = string - shared_key = optional(string) - keyvault_secret_name = optional(string) - keyvault_vault_name = optional(string) - keyvault_vault_rg = optional(string) - virtual_network_gateway_id = optional(string) - local_network_gateway_id = optional(string) - connection_protocol = optional(string) - routing_weight = optional(number) - authorization_key = optional(string) - express_route_circuit_id = optional(string) - peer_virtual_network_gateway_id = optional(string) - use_policy_based_traffic_selectors = optional(bool) - express_route_gateway_bypass = optional(bool) - dpd_timeout_seconds = optional(number) - connection_mode = optional(string) - tags_from_rg = optional(bool) - egress_nat_rule_ids = optional(list(string)) - ingress_nat_rule_ids = optional(list(string)) - local_azure_ip_address_enabled = optional(bool) - tags = optional(map(string)) - ipsec_policy = optional(object({ - dh_group = string - ike_encryption = string - ike_integrity = string - ipsec_encryption = string - ipsec_integrity = string - pfs_group = string - sa_lifetime = number - sa_datasize = number - })) - })) - default = [] -} - - diff --git a/modules/azure-vnet-gateway-connection/versions.tf b/modules/azure-vnet-gateway-connection/versions.tf deleted file mode 100644 index 64c91805b..000000000 --- a/modules/azure-vnet-gateway-connection/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.7.0" - - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "4.58.0" - } - } -} diff --git a/modules/azure-vnet-gateway/.terraform-docs.yml b/modules/azure-vnet-gateway/.terraform-docs.yml deleted file mode 100644 index 3a69365ff..000000000 --- a/modules/azure-vnet-gateway/.terraform-docs.yml +++ /dev/null @@ -1,48 +0,0 @@ -formatter: "markdown" - -version: "" - -header-from: docs/header.md -footer-from: docs/footer.md - -recursive: - enabled: false - path: modules - include-main: true - -sections: - hide: [] - show: [] - -content: "" - -output: - file: "README.md" - mode: inject - template: |- - - {{ .Content }} - - -output-values: - enabled: false - from: "" - -sort: - enabled: true - by: name - -settings: - anchor: true - color: true - default: true - description: false - escape: true - hide-empty: false - html: true - indent: 2 - lockfile: true - read-comments: true - required: true - sensitive: true - type: true diff --git a/modules/azure-vnet-gateway/README.md b/modules/azure-vnet-gateway/README.md deleted file mode 100644 index a0f4126be..000000000 --- a/modules/azure-vnet-gateway/README.md +++ /dev/null @@ -1,99 +0,0 @@ - -# **Azure Virtual Network Gateway Terraform Module** - -## Overview - -This module provisions and manages an Azure Virtual Network Gateway for VPN connectivity, supporting both Route-based and Policy-based configurations. It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. - -## Key Features - -- **Flexible Gateway Deployment**: Supports Route-based and Policy-based VPN gateways, active-active mode, and multiple SKUs. -- **Custom IP Configuration**: Allows custom public IP, subnet, and private IP allocation. -- **Advanced VPN Client Support**: Configure VPN client address spaces, protocols, and AAD integration for P2S. -- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. -- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. - -## Basic Usage - -See the main README and the `_examples/` directory for usage examples. - -```hcl -module "vnet_gateway" { - source = "./modules/azure-vnet-gateway" - vpn = { - vnet_name = "my-vnet" - gateway_subnet_name = "GatewaySubnet" - location = "westeurope" - resource_group_name = "my-rg" - gateway_name = "my-vpn-gw" - ip_name = "my-vpn-ip" - public_ip_name = "my-vpn-public-ip" - ip_allocation_method = "Dynamic" - type = "Vpn" - vpn_type = "RouteBased" - active_active = false - enable_bgp = false - sku = "VpnGw1" - # ...other optional fields... - } -} -``` - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.7.0 | -| [azurerm](#requirement\_azurerm) | 4.58.0 | - -## Providers - -| Name | Version | -|------|---------| -| [azurerm](#provider\_azurerm) | 4.58.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [azurerm_virtual_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/virtual_network_gateway) | resource | -| [azurerm_virtual_network_gateway_nat_rule.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/resources/virtual_network_gateway_nat_rule) | resource | -| [azurerm_public_ip.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/public_ip) | data source | -| [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/resource_group) | data source | -| [azurerm_subnet.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/subnet) | data source | -| [azurerm_virtual_network_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.58.0/docs/data-sources/virtual_network_gateway) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [nat\_rules](#input\_nat\_rules) | List of NAT rules for the VPN gateway |
list(object({
name = string
mode = string
type = string
ip_configuration_id = optional(string)
external_mapping_address_space = string
internal_mapping_address_space = string
}))
| `[]` | no | -| [tags](#input\_tags) | Tags to apply to resources | `map(string)` | `{}` | no | -| [tags\_from\_rg](#input\_tags\_from\_rg) | Use resource group tags as base for module tags | `bool` | `false` | no | -| [vpn](#input\_vpn) | VPN Gateway configuration object (includes P2S config) |
object({
vnet_name = string
gateway_subnet_name = string
location = string
resource_group_name = string
gateway_name = string
ip_name = string
public_ip_name = string
public_ip_id = optional(string)
ip_allocation_method = string
gateway_subnet_id = optional(string)
type = string
vpn_type = string
active_active = bool
enable_bgp = bool
sku = string
generation = optional(string)
default_local_network_gateway_id = optional(string)
edge_zone = optional(string)
private_ip_address_enabled = optional(bool)
bgp_route_translation_for_nat_enabled = optional(bool)
dns_forwarding_enabled = optional(bool)
ip_sec_replay_protection_enabled = optional(bool)
remote_vnet_traffic_enabled = optional(bool)
virtual_wan_traffic_enabled = optional(bool)

# ip_configuration block fields
private_ip_address_allocation = optional(string)

# custom_route block
custom_route_address_prefixes = optional(list(string), [])

# vpn_client_configuration block
vpn_client_address_space = optional(list(string), [])
vpn_client_protocols = optional(list(string), [])
vpn_client_aad_tenant = optional(string)
vpn_client_aad_audience = optional(string)
vpn_client_aad_issuer = optional(string)
root_certificates = optional(list(object({
name = string
public_cert = optional(string)
public_cert_data = optional(string)
})), [])
revoked_certificates = optional(list(object({
name = string
thumbprint = string
})), [])
vpn_auth_types = optional(list(string), [])

# bgp_settings block
bgp_settings = optional(object({
asn = optional(number)
peer_weight = optional(number)
peering_addresses = optional(list(object({
ip_configuration_name = optional(string)
apipa_addresses = optional(list(string))
})), [])
}))

# timeouts block
timeouts = optional(object({
create = optional(string)
read = optional(string)
update = optional(string)
delete = optional(string)
}))
})
| n/a | yes | - -## Outputs - -No outputs. - -## Examples - -For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples): - -- [basic\_route\_based](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/basic\_route\_based) - Basic RouteBased gateway example. -- [active\_active\_bgp](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/active\_active\_bgp) - Active-Active gateway with BGP enabled. -- [vpn\_client\_aad](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/vpn\_client\_aad) - Gateway with VPN Client and Azure AD authentication. - -## Remote resources - -- **Azure Virtual Network Gateway**: [azurerm\_virtual\_network\_gateway documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway) -- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) - -## Support - -For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). - \ No newline at end of file diff --git a/modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf b/modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf deleted file mode 100644 index 35f82a9bc..000000000 --- a/modules/azure-vnet-gateway/_examples/active_active_bgp/example.tf +++ /dev/null @@ -1,20 +0,0 @@ -module "vnet_gateway" { - source = "../../" - vpn = { - vnet_name = "example-vnet" - gateway_subnet_name = "GatewaySubnet" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vpn-gw" - ip_name = "example-vpn-ip" - public_ip_name = "example-vpn-public-ip" - ip_allocation_method = "Dynamic" - type = "Vpn" - vpn_type = "RouteBased" - active_active = true - enable_bgp = true - sku = "VpnGw2" - bgp_route_translation_for_nat_enabled = true - tags = { environment = "prod" } - } -} diff --git a/modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml b/modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml deleted file mode 100644 index c085af599..000000000 --- a/modules/azure-vnet-gateway/_examples/active_active_bgp/example.yaml +++ /dev/null @@ -1,17 +0,0 @@ -vpn: - vnet_name: example-vnet - gateway_subnet_name: GatewaySubnet - location: westeurope - resource_group_name: example-rg - gateway_name: example-vpn-gw - ip_name: example-vpn-ip - public_ip_name: example-vpn-public-ip - ip_allocation_method: Dynamic - type: Vpn - vpn_type: RouteBased - active_active: true - enable_bgp: true - sku: VpnGw2 - bgp_route_translation_for_nat_enabled: true - tags: - environment: prod diff --git a/modules/azure-vnet-gateway/_examples/basic_route_based/example.tf b/modules/azure-vnet-gateway/_examples/basic_route_based/example.tf deleted file mode 100644 index c12d46377..000000000 --- a/modules/azure-vnet-gateway/_examples/basic_route_based/example.tf +++ /dev/null @@ -1,19 +0,0 @@ -module "vnet_gateway" { - source = "../../" - vpn = { - vnet_name = "example-vnet" - gateway_subnet_name = "GatewaySubnet" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vpn-gw" - ip_name = "example-vpn-ip" - public_ip_name = "example-vpn-public-ip" - ip_allocation_method = "Dynamic" - type = "Vpn" - vpn_type = "RouteBased" - active_active = false - enable_bgp = false - sku = "VpnGw1" - tags = { environment = "dev" } - } -} diff --git a/modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml b/modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml deleted file mode 100644 index f8b8eead6..000000000 --- a/modules/azure-vnet-gateway/_examples/basic_route_based/example.yaml +++ /dev/null @@ -1,16 +0,0 @@ -vpn: - vnet_name: example-vnet - gateway_subnet_name: GatewaySubnet - location: westeurope - resource_group_name: example-rg - gateway_name: example-vpn-gw - ip_name: example-vpn-ip - public_ip_name: example-vpn-public-ip - ip_allocation_method: Dynamic - type: Vpn - vpn_type: RouteBased - active_active: false - enable_bgp: false - sku: VpnGw1 - tags: - environment: dev diff --git a/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf b/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf deleted file mode 100644 index 2e8e1feab..000000000 --- a/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.tf +++ /dev/null @@ -1,22 +0,0 @@ -module "vnet_gateway" { - source = "../../" - vpn = { - vnet_name = "example-vnet" - gateway_subnet_name = "GatewaySubnet" - location = "westeurope" - resource_group_name = "example-rg" - gateway_name = "example-vpn-gw" - ip_name = "example-vpn-ip" - public_ip_name = "example-vpn-public-ip" - ip_allocation_method = "Dynamic" - type = "Vpn" - vpn_type = "RouteBased" - active_active = false - enable_bgp = false - sku = "VpnGw1" - vpn_client_address_space = ["10.10.0.0/24"] - vpn_client_protocols = ["IkeV2", "OpenVPN"] - vpn_client_aad_tenant = "https://login.microsoftonline.com/" - tags = { environment = "test" } - } -} diff --git a/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml b/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml deleted file mode 100644 index e66fab766..000000000 --- a/modules/azure-vnet-gateway/_examples/vpn_client_aad/example.yaml +++ /dev/null @@ -1,22 +0,0 @@ -vpn: - vnet_name: example-vnet - gateway_subnet_name: GatewaySubnet - location: westeurope - resource_group_name: example-rg - gateway_name: example-vpn-gw - ip_name: example-vpn-ip - public_ip_name: example-vpn-public-ip - ip_allocation_method: Dynamic - type: Vpn - vpn_type: RouteBased - active_active: false - enable_bgp: false - sku: VpnGw1 - vpn_client_address_space: - - 10.10.0.0/24 - vpn_client_protocols: - - IkeV2 - - OpenVPN - vpn_client_aad_tenant: https://login.microsoftonline.com/ - tags: - environment: test diff --git a/modules/azure-vnet-gateway/data.tf b/modules/azure-vnet-gateway/data.tf deleted file mode 100644 index be11ff191..000000000 --- a/modules/azure-vnet-gateway/data.tf +++ /dev/null @@ -1,25 +0,0 @@ -## DATA SOURCES SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group -data "azurerm_resource_group" "this" { - name = var.vpn.resource_group_name -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet -data "azurerm_subnet" "this" { - name = var.vpn.gateway_subnet_name - virtual_network_name = var.vpn.vnet_name - resource_group_name = var.vpn.resource_group_name -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/public_ip -data "azurerm_public_ip" "this" { - name = var.vpn.public_ip_name - resource_group_name = var.vpn.resource_group_name -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network_gateway -data "azurerm_virtual_network_gateway" "this" { - name = var.vpn.gateway_name - resource_group_name = var.vpn.resource_group_name -} diff --git a/modules/azure-vnet-gateway/docs/footer.md b/modules/azure-vnet-gateway/docs/footer.md deleted file mode 100644 index f550568b2..000000000 --- a/modules/azure-vnet-gateway/docs/footer.md +++ /dev/null @@ -1,16 +0,0 @@ -## Examples - -For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples): - -- [basic_route_based](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/basic_route_based) - Basic RouteBased gateway example. -- [active_active_bgp](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/active_active_bgp) - Active-Active gateway with BGP enabled. -- [vpn_client_aad](https://github.com/prefapp/tfm/tree/main/modules/azure-vnet-gateway/_examples/vpn_client_aad) - Gateway with VPN Client and Azure AD authentication. - -## Remote resources - -- **Azure Virtual Network Gateway**: [azurerm_virtual_network_gateway documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway) -- **Terraform Azure Provider**: [Terraform Provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) - -## Support - -For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues). diff --git a/modules/azure-vnet-gateway/docs/header.md b/modules/azure-vnet-gateway/docs/header.md deleted file mode 100644 index 24e2ba402..000000000 --- a/modules/azure-vnet-gateway/docs/header.md +++ /dev/null @@ -1,39 +0,0 @@ -# **Azure Virtual Network Gateway Terraform Module** - -## Overview - -This module provisions and manages an Azure Virtual Network Gateway for VPN connectivity, supporting both Route-based and Policy-based configurations. It is suitable for production, staging, and development environments, and can be integrated into larger Terraform projects or used standalone. - -## Key Features - -- **Flexible Gateway Deployment**: Supports Route-based and Policy-based VPN gateways, active-active mode, and multiple SKUs. -- **Custom IP Configuration**: Allows custom public IP, subnet, and private IP allocation. -- **Advanced VPN Client Support**: Configure VPN client address spaces, protocols, and AAD integration for P2S. -- **Tag Inheritance and Customization**: Inherit tags from the resource group or specify custom tags for all resources. -- **Extensible and Modular**: Designed for easy extension and integration with other Azure network modules. - -## Basic Usage - -See the main README and the `_examples/` directory for usage examples. - -```hcl -module "vnet_gateway" { - source = "./modules/azure-vnet-gateway" - vpn = { - vnet_name = "my-vnet" - gateway_subnet_name = "GatewaySubnet" - location = "westeurope" - resource_group_name = "my-rg" - gateway_name = "my-vpn-gw" - ip_name = "my-vpn-ip" - public_ip_name = "my-vpn-public-ip" - ip_allocation_method = "Dynamic" - type = "Vpn" - vpn_type = "RouteBased" - active_active = false - enable_bgp = false - sku = "VpnGw1" - # ...other optional fields... - } -} -``` diff --git a/modules/azure-vnet-gateway/locals.tf b/modules/azure-vnet-gateway/locals.tf deleted file mode 100644 index 87520c493..000000000 --- a/modules/azure-vnet-gateway/locals.tf +++ /dev/null @@ -1,6 +0,0 @@ -## LOCALS SECTION - -locals { - # Handle tags based on whether to use resource group tags or module-defined tags - tags = var.tags_from_rg ? merge(data.azurerm_resource_group.this.tags, var.tags) : var.tags -} diff --git a/modules/azure-vnet-gateway/main.tf b/modules/azure-vnet-gateway/main.tf deleted file mode 100644 index c59cac56b..000000000 --- a/modules/azure-vnet-gateway/main.tf +++ /dev/null @@ -1,88 +0,0 @@ -## VPN SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway -resource "azurerm_virtual_network_gateway" "this" { - name = var.vpn.gateway_name - location = var.vpn.location - resource_group_name = var.vpn.resource_group_name - type = var.vpn.type - vpn_type = var.vpn.vpn_type - sku = var.vpn.sku - tags = local.tags - active_active = var.vpn.active_active - enable_bgp = var.vpn.enable_bgp - generation = var.vpn.generation - default_local_network_gateway_id = var.vpn.default_local_network_gateway_id - edge_zone = var.vpn.edge_zone - private_ip_address_enabled = var.vpn.private_ip_address_enabled - bgp_route_translation_for_nat_enabled = var.vpn.bgp_route_translation_for_nat_enabled - dns_forwarding_enabled = var.vpn.dns_forwarding_enabled - ip_sec_replay_protection_enabled = var.vpn.ip_sec_replay_protection_enabled - remote_vnet_traffic_enabled = var.vpn.remote_vnet_traffic_enabled - virtual_wan_traffic_enabled = var.vpn.virtual_wan_traffic_enabled - - ip_configuration { - name = var.vpn.ip_name - subnet_id = data.azurerm_subnet.this.id - public_ip_address_id = data.azurerm_public_ip.this.id - private_ip_address_allocation = var.vpn.private_ip_address_allocation - } - - custom_route { - address_prefixes = var.vpn.custom_route_address_prefixes - } - - dynamic "vpn_client_configuration" { - for_each = length(var.vpn.vpn_client_address_space) > 0 ? [1] : [] - content { - address_space = var.vpn.vpn_client_address_space - vpn_client_protocols = var.vpn.vpn_client_protocols - aad_tenant = var.vpn.vpn_client_aad_tenant - aad_audience = var.vpn.vpn_client_aad_audience - aad_issuer = var.vpn.vpn_client_aad_issuer - dynamic "root_certificate" { - for_each = var.vpn.root_certificates - content { - name = root_certificate.value.name - public_cert_data = coalesce( - root_certificate.value.public_cert_data, - root_certificate.value.public_cert - ) - } - } - dynamic "revoked_certificate" { - for_each = var.vpn.revoked_certificates - content { - name = revoked_certificate.value.name - thumbprint = revoked_certificate.value.thumbprint - } - } - vpn_auth_types = var.vpn.vpn_auth_types - } - } - - dynamic "bgp_settings" { - for_each = var.vpn.bgp_settings != null ? [1] : [] - content { - asn = var.vpn.bgp_settings.asn - peer_weight = var.vpn.bgp_settings.peer_weight - dynamic "peering_addresses" { - for_each = try(var.vpn.bgp_settings.peering_addresses, []) - content { - ip_configuration_name = peering_addresses.value.ip_configuration_name - apipa_addresses = peering_addresses.value.apipa_addresses - } - } - } - } - - dynamic "timeouts" { - for_each = var.vpn.timeouts != null ? [1] : [] - content { - create = var.vpn.timeouts.create - read = var.vpn.timeouts.read - update = var.vpn.timeouts.update - delete = var.vpn.timeouts.delete - } - } -} diff --git a/modules/azure-vnet-gateway/variables.tf b/modules/azure-vnet-gateway/variables.tf deleted file mode 100644 index c338a9198..000000000 --- a/modules/azure-vnet-gateway/variables.tf +++ /dev/null @@ -1,97 +0,0 @@ -## VARIABLES SECTION - -variable "vpn" { - description = "VPN Gateway configuration object (includes P2S config)" - type = object({ - vnet_name = string - gateway_subnet_name = string - location = string - resource_group_name = string - gateway_name = string - ip_name = string - public_ip_name = string - public_ip_id = optional(string) - ip_allocation_method = string - gateway_subnet_id = optional(string) - type = string - vpn_type = string - active_active = bool - enable_bgp = bool - sku = string - generation = optional(string) - default_local_network_gateway_id = optional(string) - edge_zone = optional(string) - private_ip_address_enabled = optional(bool) - bgp_route_translation_for_nat_enabled = optional(bool) - dns_forwarding_enabled = optional(bool) - ip_sec_replay_protection_enabled = optional(bool) - remote_vnet_traffic_enabled = optional(bool) - virtual_wan_traffic_enabled = optional(bool) - - # ip_configuration block fields - private_ip_address_allocation = optional(string) - - # custom_route block - custom_route_address_prefixes = optional(list(string), []) - - # vpn_client_configuration block - vpn_client_address_space = optional(list(string), []) - vpn_client_protocols = optional(list(string), []) - vpn_client_aad_tenant = optional(string) - vpn_client_aad_audience = optional(string) - vpn_client_aad_issuer = optional(string) - root_certificates = optional(list(object({ - name = string - public_cert = optional(string) - public_cert_data = optional(string) - })), []) - revoked_certificates = optional(list(object({ - name = string - thumbprint = string - })), []) - vpn_auth_types = optional(list(string), []) - - # bgp_settings block - bgp_settings = optional(object({ - asn = optional(number) - peer_weight = optional(number) - peering_addresses = optional(list(object({ - ip_configuration_name = optional(string) - apipa_addresses = optional(list(string)) - })), []) - })) - - # timeouts block - timeouts = optional(object({ - create = optional(string) - read = optional(string) - update = optional(string) - delete = optional(string) - })) - }) -} - -variable "nat_rules" { - description = "List of NAT rules for the VPN gateway" - type = list(object({ - name = string - mode = string - type = string - ip_configuration_id = optional(string) - external_mapping_address_space = string - internal_mapping_address_space = string - })) - default = [] -} - -variable "tags_from_rg" { - description = "Use resource group tags as base for module tags" - type = bool - default = false -} - -variable "tags" { - description = "Tags to apply to resources" - type = map(string) - default = {} -} diff --git a/modules/azure-vnet-gateway/versions.tf b/modules/azure-vnet-gateway/versions.tf deleted file mode 100644 index 64c91805b..000000000 --- a/modules/azure-vnet-gateway/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.7.0" - - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "4.58.0" - } - } -} diff --git a/modules/azure-vnet-gateway/vpn_nat_rule.tf b/modules/azure-vnet-gateway/vpn_nat_rule.tf deleted file mode 100644 index 5cb323944..000000000 --- a/modules/azure-vnet-gateway/vpn_nat_rule.tf +++ /dev/null @@ -1,23 +0,0 @@ -## VPN NAT RULE SECTION - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway_nat_rule -resource "azurerm_virtual_network_gateway_nat_rule" "this" { - for_each = { for idx, rule in var.nat_rules : idx => rule } - name = each.value.name - resource_group_name = var.vpn.resource_group_name - virtual_network_gateway_id = azurerm_virtual_network_gateway.this.id - mode = each.value.mode - type = each.value.type - ip_configuration_id = coalesce( - try(each.value.ip_configuration_id, null), - data.azurerm_virtual_network_gateway.this.ip_configuration[0].id - ) - - external_mapping { - address_space = each.value.external_mapping_address_space - } - - internal_mapping { - address_space = each.value.internal_mapping_address_space - } -} From 7ce2e42b209ba3e237f4620c3b244e2976e6ed81 Mon Sep 17 00:00:00 2001 From: jcframil Date: Mon, 9 Mar 2026 16:50:30 +0100 Subject: [PATCH 54/54] feat: release-please module Signed-off-by: jcframil --- release-please-config.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/release-please-config.json b/release-please-config.json index 2e4219f71..fe945aca7 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -147,6 +147,15 @@ }, "modules/aws-secretsmanager-replication": { "package-name": "aws-secretsmanager-replication" + }, + "modules/azure-vnet-gateway": { + "package-name": "azure-vnet-gateway" + }, + "modules/azure-vnet-gateway-connection": { + "package-name": "azure-vnet-gateway-connection" + }, + "modules/azure-localnet-gateway": { + "package-name": "azure-localnet-gateway" } } }