Search code examples
azureterraformterraform-provider-azureterraform0.12+terraform-template-file

Can we create subnets, route tables, and NSGs in virtual network resource blocks or subnet blocks using Dynamic in Terraform for Azure?


Can we create subnets, route tables, and NSGs in virtual network resource blocks or subnet blocks using Dynamic in Terraform for Azure?

please let me know or can anyone provide code with short example.

resource "azurerm_subnet" "subnets" {
  for_each                                      = var.subnets
  name                                          = each.key
  resource_group_name                           = var.resource_group_name
  address_prefixes                              = [each.value.addressPrefix]
  virtual_network_name                          = azurerm_virtual_network.Virtual_Network.name
  private_endpoint_network_policies_enabled     = each.value.privateEndpointNetworkPolicies
  private_link_service_network_policies_enabled = each.value.privateLinkServiceNetworkPolicies
  service_endpoints                             = each.value.service_endpoints

  dynamic "route_table" {
    for_each = subnets.value.route_table
    content {
      name                          = route_table.value.name
      disable_bgp_route_propagation = route_table.value.disableBgpRoutePropagation

      dynamic "route" {
        for_each = route_table.value.routes
        content {
          name                = route.value.name
          address_prefix      = route.value.addressPrefix
          next_hop_type       = route.value.nextHopType
          next_hop_ip_address = route.value.nextHopIpAddress
        }
      }
    }
  }

variable "subnets" {
  type = map(object({
    addressPrefix                     = string
    privateEndpointNetworkPolicies    = string
    privateLinkServiceNetworkPolicies = string
    service_endpoints                 = list(string)
    route_tables = object({
      name                       = string
      disableBgpRoutePropagation = bool
      routes = list(object({
        name             = string
        addressPrefix    = string
        nextHopType      = string
        nextHopIpAddress = string
      }))
    })
  }))
}

Solution

  • Yes, Azure subnets, route tables, security groups, and virtual networks can be configured with dynamic blocks in Terraform.

    For example, here's how to iterate over the "subnets" variable from your question:

    variable "subnets" {
      type = map(object({
        addressPrefix                     = string
        privateEndpointNetworkPolicies    = string
        privateLinkServiceNetworkPolicies = string
        service_endpoints                 = list(string)
        route_tables = object({
          name                       = string
          disableBgpRoutePropagation = bool
          routes = list(object({
            name             = string
            addressPrefix    = string
            nextHopType      = string
            nextHopIpAddress = string
          }))
        })
      }))
    }
    
    resource "azurerm_subnet" "subnet_x" {
      for_each = var.subnets
    
      name                 = each.key
      resource_group_name  = azurerm_resource_group.res_group_x.name
      virtual_network_name = azurerm_virtual_network.vn_x.name
      address_prefixes     = [each.value.addressPrefix]
      service_endpoints    = each.value.service_endpoints
    
      private_endpoint_network_policies    = each.value.privateEndpointNetworkPolicies
      private_link_service_network_policies = each.value.privateLinkServiceNetworkPolicies
    }
    
    resource "azurerm_route_table" "rt_x" {
      for_each = var.subnets
    
      name                = each.value.route_tables.name
      location            = azurerm_resource_group.res_group_x.location
      resource_group_name = azurerm_resource_group.res_group_x.name
    
      disable_bgp_route_propagation = each.value.route_tables.disableBgpRoutePropagation
    
      route {
        for r in each.value.route_tables.routes : {
          name                   = r.name
          address_prefix         = r.addressPrefix
          next_hop_type          = r.nextHopType
          next_hop_in_ip_address = r.nextHopIpAddress
        }
      }
    }
    
    resource "azurerm_subnet_route_table_association" "rt_assoc_x" {
      for_each = var.subnets
    
      subnet_id      = azurerm_subnet.subnet_x[each.key].id
      route_table_id = azurerm_route_table.rt_x[each.key].id
    }
    

    In-line subnets are avoided above to limit nesting. "for_each" is used to iterate over the "subnets" variable since it's a map, and a "for" expression is used to iterate over routes since it's a list.

    See docs for dynamic blocks, "for" expressions, and azurerm_subnet