title: Terraform - how to use for_each loop on a list of objects to create resources
body: <p>I have an object containing the list of subnets I want to create.</p>
  
  <pre><code>variable "subnet-map" {
    default = {
      ec2 = [
        {
          cidr_block        = "10.0.1.0/24"
          availability_zone = "eu-west-1a"
        }
      ],
      lambda = [
        {
          cidr_block        = "10.0.5.0/24"
          availability_zone = "eu-west-1a"
        },
        {
          cidr_block        = "10.0.6.0/24"
          availability_zone = "eu-west-1b"
        },
        {
          cidr_block        = "10.0.7.0/24"
          availability_zone = "eu-west-1c"
        }
      ],
      secrets = [
        {
          cidr_block        = "10.0.8.0/24"
          availability_zone = "eu-west-1a"
        },
        {
          cidr_block        = "10.0.9.0/24"
          availability_zone = "eu-west-1b"
        },
        {
          cidr_block        = "10.0.10.0/24"
          availability_zone = "eu-west-1c"
        }
      ],
      rds = [
        {
          cidr_block        = "10.0.11.0/24"
          availability_zone = "eu-west-1a"
        },
        {
          cidr_block        = "10.0.12.0/24"
          availability_zone = "eu-west-1b"
        },
        {
          cidr_block        = "10.0.13.0/24"
          availability_zone = "eu-west-1c"
        }
      ]
    }
  }
  </code></pre>
  
  <p>Earlier I was using the count loop construct. So I used to flatten the above structure into a list of objects</p>
  
  <pre><code>locals {
    subnets = flatten([
      for resource in keys(var.subnet-map) : [
        for subnet in var.subnet-map[resource] : {
          resource          = resource
          cidr_block        = subnet.cidr_block
          availability_zone = subnet.availability_zone
        }
      ]
    ])
  }
  </code></pre>
  
  <p>And then I would create the resources by doing</p>
  
  <pre><code>resource "aws_subnet" "aws-subnets" {
    count             = length(local.subnets)
    vpc_id            = aws_vpc.aws-vpc.id
    cidr_block        = local.subnets[count.index].cidr_block
    availability_zone = local.subnets[count.index].availability_zone
  
    tags = {
      Name = "subnet-${local.subnets[count.index].resource}-${local.subnets[count.index].availability_zone}"
    }
  }
  </code></pre>
  
  <p>Now I want to use the for_each loop. But I cannot figure out how to do it. This is what I've done so far.</p>
  
  <pre><code>resource "aws_subnet" "subnets-dev" {
    for_each          = var.subnet-map
    vpc_id            = aws_vpc.vpc-dev.id
    cidr_block        = each.value.cidr_block
    availability_zone = each.value.availability_zone
  
    tags = {
      Name        = "subnet-dev-${each.value.resource}-${each.value.availability_zone}"
      environment = "dev"
    }
  }
  </code></pre>
  
  <p>But it keeps giving an error saying</p>
  
  <pre><code>Error: Unsupported attribute
  
    on vpc/main.tf line 93, in resource "aws_subnet" "subnets-dev":
    93:     Name        = "subnet-dev-${each.value.resource}-${each.value.availability_zone}"
      |----------------
      | each.value is tuple with 3 elements
  
  This value does not have any attributes.
  </code></pre>
  
  <p>How could I fix this?</p>