azureterraform

terraform azure udr reading subnets from variable


I'm on the newer side to tf but enjoying what i can automate so far. i'm in a situation where i need to update several UDR's based on a list of networks defining the internal networks at company A. I can build the route statements in tf no prob but i'd like to make it more dynamic and easier to update.

what i'd like to do is

resource "azurerm_route_table" "example1" {
    name = "example_udr"
    location = var.location_name
    resource_group = var.resource_group_name

    for subnet in var.subnets {
        route {
           name = "net-${subnet}"
           address_prefix = subnet
           next_hop_type = "virtualAppliance"
           next_hop_in_ip_address = var.fw_vip
        }
     }
}

i wanted to have something in the variable file like

variable "subnets" {
    type       = map(any)
    default    = {
        subnet_1 = {
            "name" = "net-1"
            "address_prefix" = "10.0.0.0/16"
        }
        subnet_2 = {
            "name" = "net-1"
            "address_prefix" = "10.10.0.0/16"
        }
    }
}

every time i try to validate or apply this i get a LOT of errors.

maybe i'm expecting too much and wanting a more robust programming language for this; but i have other cases where i want to read a list or map to build things out.

i've had way too many browser tabs open trying to find an example of how to do this and have not seen anything related to this.

has anyone run into a solution for something like this or similar ?

much thanks, g

web searches and code samples
everything else referenced adding multiple resources but not looping on things within a resource


Solution

  • Azure udr reading subnets from variable while using terraform

    Issue seems to be with way you declare for loop inside route block which in general was not a valid decalartion. This approach of passing dynamic loops should not be defined as mentioned.

    The other change is the declaring of subnets variables is map(any) which we do commonly but here total structural mismatch happens.

    Instead of this you can use a for_each block which is ideally suitable for dynamically creating resources based on map or list

    demo configuration:

    variable "fw_vip" {
      description = "Firewall VIP address"
      type        = string
    }
    
    variable "subnets" {
      description = "Map of subnets with route details"
      type = map(object({
        name           = string
        address_prefix = string
      }))
    }
    
    resource "azurerm_route_table" "example" {
      name                = "vinay-udr"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    
      dynamic "route" {
        for_each = var.subnets
        content {
          name                   = route.value.name
          address_prefix         = route.value.address_prefix
          next_hop_type          = "VirtualAppliance"
          next_hop_in_ip_address = var.fw_vip
        }
      }
    }
    
    

    Deployment:

    enter image description here

    enter image description here

    refer:

    https://developer.hashicorp.com/terraform/language/meta-arguments/for_each

    https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks

    https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/route_table