skip to Main Content

I need a bit of help, trying to create a site-to-site vpn is Azure.
This is the map I am using to define it:

  local_network_gateways = {
    vpn1 = { 
      lng_gateway_address = "193.176.222.22", 
      lng_address_space = ["10.18.0.0/16"], 
      enabled = true,
      connections = [
        {
          name             = "vpn1-connection1",
          connection_type  = "VNet2VNet",
          vpn_shared_key   = "somegibetrrish",
          enabled          = true
        },
        {
          name             = "vpn1-connection2",
          connection_type  = "IPsec",
          vpn_shared_key   = "somegiberrish",
          enabled          = true
        }
      ]
    },
    vpn2 = { 
      lng_gateway_address = "194.176.223.23", 
      lng_address_space = ["12.44.0.0/16"], 
      enabled = true,
      connections = [
        {
          name             = "vpn2-connection1"
          connection_type  = "IPsec"
          vpn_shared_key   = "vpn2_somegibetrrish"
          enabled          = true
        }
      ]
    }
  }

And I need to understand the nested for_each loops I need to build, in order to create as many azurerm_virtual_network_gateway_connection resources as I have connections, for each of the local_network_gateways.

For the local variable above, the loop should help me create 3 azurerm_virtual_network_gateway_connection, but each of them should be connected to the proper local_network_gateway_id

resource "azurerm_local_network_gateway" "lng_prod" {
  for_each = { 
    for key, value in var.local_network_gateways : key => value
    if value.enabled
  }

  name                = each.key
  location            = var.location
  resource_group_name = var.resource_group_name
  gateway_address     = each.value.lng_gateway_address
  address_space       = each.value.lng_address_space
}

resource "azurerm_virtual_network_gateway_connection" "vng_connection" {
  for_each = local.local_network_gateways_map

  name                = each.key
  location            = var.location
  resource_group_name = var.resource_group_name

  type  = each.value.connection_type

  virtual_network_gateway_id = azurerm_virtual_network_gateway.vpn[0].id
  local_network_gateway_id   = azurerm_local_network_gateway.lng_prod[each.key].id --<<<< there's the problem

  shared_key                         = each.value.connections[0].vpn_shared_key
  connection_protocol                = "IKEv2"
  dpd_timeout_seconds                = each.value.connections[0].dpd_timeout_seconds
  enable_bgp                         = each.value.connections[0].vngc_enable_bgp
  express_route_gateway_bypass       = each.value.connections[0].vngc_express_route_gateway_bypass
  local_azure_ip_address_enabled     = each.value.connections[0].vngc_local_azure_ip_address_enabled
  use_policy_based_traffic_selectors = each.value.connections[0].vngc_use_policy_based_traffic_selectors
  routing_weight                     = 0

  ipsec_policy {
    dh_group         = each.value.connections[0].dh_group
    ike_encryption   = each.value.connections[0].ike_encryption
    ike_integrity    = each.value.connections[0].ike_integrity
    ipsec_encryption = each.value.connections[0].ipsec_encryption
    ipsec_integrity  = each.value.connections[0].ipsec_integrity
    pfs_group        = each.value.connections[0].pfs_group
    sa_datasize      = each.value.connections[0].sa_datasize
    sa_lifetime      = each.value.connections[0].sa_lifetime
  }

  tags = {
    software        = each.value.connections[0].software
    environment     = each.value.connections[0].environment
    customer        = each.value.connections[0].customer
    special_purpose = each.value.connections[0].special_purpose
  }
}

What I got so far is this:

+  all_connections = flatten([
    for k, v in local.local_network_gateways : {
      for conn_k, conn_v in v.connections : "${k}_${conn_v.name}" => conn_v
    }
  ])
}

output "testme" {
  value = local.all_connections
}

and the output is:

testme = [
  {
    "vpn1_connection1" = {
      "connection_type" = "VNet2VNet"
      "enabled" = true
      "name" = "vpn1-connection1"
      "vpn_shared_key" = "somegibetrrish"
    }
    "vpn1_connection2" = {
      "connection_type" = "IPsec"
      "enabled" = true
      "name" = "vpn1-connection2"
      "vpn_shared_key" = "somegiberrish"
    }
  },
  {
    "vpn2_connection1" = {
      "connection_type" = "dasdwawdw"
      "enabled" = true
      "name" = "vpn2-connection1"
      "vpn_shared_key" = "vpn2_somegibetrrish"
    }
  },
]

But I cannot understand how to make the connection between the connection and its local_network_gateway, aka:

  local_network_gateway_id   = azurerm_local_network_gateway.lng_prod[each.key].id

and how to define the rest of the azurerm_virtual_network_gateway_connection attributes based of the loop’s result.
Thank you!

2

Answers


  1. Chosen as BEST ANSWER

    So to answer my question, these are the locals:

    locals {
      local_network_gateways_loop = flatten([
        for k, v in var.local_network_gateways : [
          for conn_k, conn_v in v.connections : {
            lng_name                                = k
            conn_name                               = conn_k
            connection_type                         = conn_v.connection_type
            vpn_shared_key                          = conn_v.vpn_shared_key
            dpd_timeout_seconds                     = conn_v.dpd_timeout_seconds
            vngc_enable_bgp                         = conn_v.vngc_enable_bgp
            vngc_express_route_gateway_bypass       = conn_v.vngc_express_route_gateway_bypass
            vngc_local_azure_ip_address_enabled     = conn_v.vngc_local_azure_ip_address_enabled
            vngc_use_policy_based_traffic_selectors = conn_v.vngc_use_policy_based_traffic_selectors
            dh_group                                = conn_v.dh_group
            ike_encryption                          = conn_v.ike_encryption
            ike_integrity                           = conn_v.ike_integrity
            ipsec_encryption                        = conn_v.ipsec_encryption
            ipsec_integrity                         = conn_v.ipsec_integrity
            pfs_group                               = conn_v.pfs_group
            sa_datasize                             = conn_v.sa_datasize
            sa_lifetime                             = conn_v.sa_lifetime
            software                                = conn_v.software
            environment                             = conn_v.environment
            customer                                = conn_v.customer
            special_purpose                         = conn_v.special_purpose
            enabled                                 = conn_v.enabled
          }
        ]
      ])
      
      all_connections_map = { for idx, conn in local.local_network_gateways_loop : idx => conn }
    }

    and this is how it's used:

    resource "azurerm_virtual_network_gateway_connection" "vng_connection" {
      for_each = local.all_connections_map
    
      name                = each.value.conn_name
      location            = var.location
      resource_group_name = var.resource_group_name
    
      type                = each.value.connection_type
    
      virtual_network_gateway_id = azurerm_virtual_network_gateway.vpn[0].id
      local_network_gateway_id   = azurerm_local_network_gateway.lng_prod[each.value.lng_name].id
      ...


  2. You have to use merge to flatten your local.all_connections:

    locals {
      all_connections = merge(flatten([
        for k, v in local.local_network_gateways : {
          for conn_k, conn_v in v.connections : "${k}_${conn_v.name}" => conn_v
        }
      ])...) # the Dots are important - do NOT remove
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search