Use indexing in for_each and for in terraform

I am trying to create multiple VPC and Subnets using for_each and for. Below is the code and error. I am having trouble figuring out the index while using for_each. It's easier using count but the requirement is to use for_each.

main.tf

resource "aws_vpc" "VPC" {
  for_each = { for vpc in var.vpc : vpc.name => vpc}
  cidr_block            = each.value.cidr
  enable_dns_hostnames  = true
  enable_dns_support    = true
}

####### Additional CIDR for VPC ########
resource "aws_vpc_ipv4_cidr_block_association" "VPCExtraCidrBlock" {
  for_each = local.extra_cidr_list 
  vpc_id      = aws_vpc.VPC[each.value.vpc].id
  cidr_block  = each.value.extra_cidr
}


resource "aws_internet_gateway" "igw" {
  for_each = { for vpc in var.vpc : vpc.name => vpc if vpc.igw == true}
  vpc_id  = aws_vpc.VPC[each.value.name].id
}

########### Private subnets #############
resource "aws_subnet" "VPCPrivateSubnetA" {
  for_each = local.privateA_cidr_list
  vpc_id                  = aws_vpc.VPC[each.value.vpc].id
  cidr_block              = each.value.privateA
  availability_zone       = element(var.AvailabilityZonesForVPC,0)
}
resource "aws_subnet" "VPCPublicSubnetA" {
  for_each = local.publicA_cidr_list
  vpc_id                  = aws_vpc.VPC[each.value.vpc].id
  cidr_block              = each.value.publicA
  availability_zone       = element(var.AvailabilityZonesForVPC,0)

}


local.tf

I am trying to format the variables in local.tf and use for_each on them.

locals {
  extra_cidr_list = flatten([
    for idx_vpc, vpc in var.vpc: 
    [ for idx, cidr in vpc.extra_cidr :
     { vpc = vpc.name,
      extra_cidr = cidr[idx]
      } if length(vpc.extra_cidr) > 0 ] ])

  publicA_cidr_list = flatten([ for idx_vpc, vpc in var.vpc : [ for idx, cidr in vpc[idx_vpc].publicA : { vpc = vpc.name, publicA = cidr[idx] } if length(vpc[idx_vpc].publicA) > 0 ] ])

  privateA_cidr_list = flatten([ for idx_vpc, vpc in var.vpc : [ for idx, cidr in vpc[idx_vpc].privateA : { vpc = vpc.name, privateA = cidr[idx] } if length(vpc[idx_vpc].privateA) > 0 ] ])
}

module.tf

module "VPC" {
  source = "./modules/VPC"
  vpc = var.vpc
}

tfvars file

vpc = [
{
name = "VPC1"
cidr = "10.150.0.0/20"
publicA            = ["10.150.0.0/23"]       
privateA           = ["10.150.9.0/26","10.150.7.0/24"] 
igw = true
extra_cidr = ["10.151.0.0/20"]
},
{
name = "VPC2"
cidr = "192.168.0.0/22"
publicA            = ["192.168.0.0/25","192.168.0.128/25","192.168.3.0/25"]                     #list of IPs
privateA           = [] 
igw = false
extra_cidr = []
}
]

Please help.


Your locals are incorrect. They should be:

locals {

  extra_cidr_list = flatten([
    for idx_vpc, vpc in var.vpc: 
       [ 
         for idx, cidr in vpc.extra_cidr :
         { 
            vpc = vpc.name,
            extra_cidr = cidr
         } if length(vpc.extra_cidr) > 0 ] ])

  publicA_cidr_list = flatten(
        [ for idx_vpc, vpc in var.vpc : 
            [ for idx, cidr in vpc.publicA : 
               { 
                  vpc = vpc.name, 
                  publicA = cidr
              } if length(vpc.publicA) > 0 ] ])

  privateA_cidr_list = flatten([ 
       for idx_vpc, vpc in var.vpc : 
         [ 
           for idx, cidr in vpc.privateA : 
           { 
             vpc = vpc.name, 
             privateA = cidr 
           } if length(vpc.privateA) > 0 ] ])
}