How can i get an attribute value from a map within a map?

Is there a way to get the attribute value from a map within a map?

variable "vpc" {
  type = map(object({
    vpc_cidr_block                   = string
    instance_tenancy                 = optional(string, null)
    enable_dns_support               = optional(bool, null)
    enable_dns_hostnames             = optional(bool, null)
    assign_generated_ipv6_cidr_block = optional(bool, null)
    tags                             = optional(map(string), { "created_by" : "terraform" })
    subnets = map(object({
      subnet_cidr_block = string
    }))
  }))
  description = "Map variable to create a new VPC"
}
resource "aws_subnet" "this" {
  for_each   = var.vpc
  vpc_id     = aws_vpc.this[each.key].id
  cidr_block = each.value.subnets[each.key].subnet_cidr_block
}

I want to get the attribute value from the subnet_cidr_block

It’s giving me this error

│ Error: Invalid index
│
│   on ../../../modules/aws/vpc/main.tf line 15, in resource "aws_subnet" "this":
│   15:   cidr_block = each.value.subnets[each.key].subnet_cidr_block
│     ├────────────────
│     │ each.key is "test"
│     │ each.value.subnets is map of object with 1 element
│
│ The given key does not identify an element in this collection value.

I can’t find anything to resolve my problem!

Thanks in advance guys :smiley:

Hi @lesardinhas,

The way you’ve written that aws_subnet configuration seems to assume that there’s only one subnet per VPC and that the subnet always has the same key as the VPC it’s nested inside, which I assume isn’t the case because otherwise it would be pointless to have the subnets as a nested map.

I expect that what you really want to do here is declare one instance of aws_subnet.this for every subnet across all of your VPCs, which means that you need to set that resource’s for_each to be a collection that has one element per subnet, rather than one element per VPC.

This particular case of AWS VPCs and subnets happens to be exactly the situation used as an example in the documentation section Flattening nested structures for for_each, which shows one way to achieve this using the flatten function and a for expression.

There are some other ways to get a similar result with different functions, but I’d suggest trying what that example shows first and see how that works out. If you run into trouble with it then please share your updated configuration and then we can talk about any adaptations to suit your specific input variable structure.

Thank you very much @apparentlymart it was so obvious i feel embarrassed :rofl:, it worked perfectly!

No need to be embarrassed! If it were so obvious then there wouldn’t be a worked example in the documentation. :grinning: