Goal: (How to dynamically populate an object variable "subnets")

My aim is to just change a base cidr block e.g. 10.10.0.0/20 in this case, and then automatically create subnets in each AZ, with a given tier and a /24 ip range.
(see variable “subnets” default version for an explicit example)
The default values in var.subnets work.

What I’m trying to achieve is to dynamically populate the subnets variable, populated via local variables of result and cidrlist

terraform version
Terraform v1.0.2

I’m reasonably new to tf also as a note

Initial setup

variables.tf

variable "region" {
  type    = string
  default = "us-east-1"
}
variable "tiers" {
  type = list(string)
  default = [
    "app",
    "data",
    "web",
    "elb"
  ]
}
variable "multi_az_lettering" {
  default = [
    "a",
    "b",
    "c",
  ]
}
variable "azs" {
  type = list(list(string))
  default = [[
    "us-east-1",
    "a",
    ],
    [
      "us-east-1",
      "b",
  ]]
}
variable "subnets" {
  type = list(object({
    cidr = string
    az   = list(string)
    tier = string
  }))
  default = [
    {
      cidr = "10.0.0.0/24",
      az   = ["us-east-1", "a", ],
      tier = "app",
    },
    {
      cidr = "10.0.1.0/24",
      az   = ["us-east-1", "a", ],
      tier = "data",
    }
  ]
}

main.tf

locals {
  
  result =  setproduct(setproduct([var.region], var.multi_az_lettering), var.tiers)
  # subnet_count = length(local.result) # 12
  cidrlist = [for index in range(12): cidrsubnet("10.10.0.0/20", 4, index)]
  subnet_count = 2 # Set for easier observations
}
module "subnets" {
  source       = "./modules/subnets"
  region       = var.region
  vpc_id       = module.vpc.vpc_id
  
  requested_cidrs = [for index in range(local.subnet_count) : cidrsubnet(var.cidr, 4, index)]
  
  tiers           = [for index in range(length(var.tiers)) : var.tiers[index]]
  author          = var.author

  # azs = var.azs
  subnets = var.subnets # Works for default values
 
  # dynamic "info" {
  #     for_each = local.result
  #     content {
  #       az = info.value
  #       tier   = info.value
  #     }
  #   }
  # subnets = {
  #   cidr = [for index in range(1): cidrsubnet("10.10.0.0/20", 4, index)]
  #   az = [for index in range(local.subnet_count): ["us-east-1","a",]] # was index[0]
  #   tier = [for index in range(local.subnet_count): "data"] # was index[1]
  #   # }
  # }
}

In modules/subnets directory I have:

resource "aws_subnet" "this" {
  vpc_id = var.vpc_id

  for_each = {for subnet in var.subnets:  subnet.cidr => subnet}
  cidr_block = each.value.cidr

  availability_zone = join("", [each.value.az[0], each.value.az[1]])

  tags = {
    "Name"       = join("-", [each.value.tier, "subnet"]),
    "created-by" = var.author,
    "AZ"   = join("", [each.value.az[0], each.value.az[1]])
  }
}

Notes:
1 - Snippet of setproduct output

setproduct(setproduct([var.region], var.multi_az_lettering), var.tiers)
tolist([
  [
    [
      "us-east-1",
      "A",
    ],
    "app",
  ],
  [
    [
      "us-east-1",
      "A",
    ],
    "data",
  ],
```Preformatted text

To dynamically create subnets in Terraform based on a base CIDR block, availability zones, and tiers, you can use a combination of locals , setproduct , and cidrsubnet functions: [Ill DM you]