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
}))
})
}))
}
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