I am trying to use the terraform ‘setproduct’ function example scenario to replicate the exact scenario being illustrated
[https://www.terraform.io/docs/configuration/functions/setproduct.html](https://setproduct function documenation)
I need to create multiple Azure VNETs, and create multiple Azure Subnets for each of those VNETs.
To achieve this, I am trying to use setproduct, along with the type = map(object({ })) variable types, and locals.
When I pass the var.networks, and var.subnets inputs at the module, it gives the following errors:
**I realize I may not understand how the map(object) wants the passed in ‘string’
Code to help explain my scenario:
tf variables:
variable "networks" {
type = map(object({
base_cidr_block = string
}))
}
variable "subnets" {
type = map(object({
bits = string
}))
}
network.tf
locals {
vnet_name_prefix = "${var.project_ident}-${var.env_ident}-vnet-${var.region_suffix}"
subnet_name_prefix = "${var.project_ident}-${var.env_ident}-subnet-${var.region_suffix}"
networks = [
for key, network in var.networks : {
key = key
cidr_block = network.base_cidr_block
}
]
subnets = [
for key, subnet in var.subnets : {
key = key
number = subnet.bits
}
]
network_subnets = [
for pair in setproduct(local.networks, local.subnets) : {
network_key = pair[0].key
subnet_key = pair[1].key
network_name = azurerm_virtual_network.vnet[pair[0].key].name
cidr_block = cidrsubnet(pair[0].cidr_block, 4, pair[1].number)
}
]
}
resource "azurerm_virtual_network" "vnet" {
for_each = var.networks
resource_group_name = var.resource_group_name
location = var.location
address_space = [each.value.base_cidr_block]
name = join("- ", [local.vnet_name_prefix, substr(each.value.base_cidr_block, 0, length(each.value.base_cidr_block)-3)])
}
resource "azurerm_subnet" "bastion-sub" {
for_each = var.networks
name = var.subnet1_name # Name must match 'AzureBastionSubnet'
resource_group_name = var.resource_group_name
vitual_network_name = join("- ", [local.vnet_name_prefix, substr(each.value.base_cidr_block, 0, length(each.value.base_cidr_block)-3)])
address_prefixes = [cidrsubnet(each.value.base_cidr_block, 11, 0)]
depends_on = [azurerm_virtual_network.vnet]
}
resource "azurerm_subnet" "subnets" {
for_each = {
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
}
name = join("- ", [local.subnet_name_prefix, substr(each.each.value_cidr_block, 0, length(each.value)-3)])
resource_group_name = var.resource_group_name
virtual_network_name = each.value.network_name
address_prefixes = [each.value.cidr_block]
}
Calling the network module, and passing in the vars used through out the locals:
module "network" {
source = "../../modules/network"
project_ident = var.project_ident
env_ident = var.env_ident
region_suffix = var.region_suffix
resource_group_name = data.azurerm_resource_group.core-rg.name
location = data.azurerm_resource_group.core-rg.location
networks = ["10.1.0.0/16","10.2.0.0/16"]
subnets = [1,2,3]
}
Ive tried to turn this list into a map, but no matter how i try it, i get the following errors
networks = tomap(["10.1.0.0/16","10.2.0.0/16"])
subnets = tomap([1,2,3])
Thank you for any help on this
I am new to using these complex terraform for_each and for expressions, but this would really help make a very dynamic network module, to allow multiple vnets with custom cidrs, and multiple subnet with custom cidrs