0.13-rc1 - Reference module that uses for_each

I’m testing out TF 13, and am just getting my head around what is possible or not. The idea here is to create a subnet (in 3 AZ’s) PER module that is being created. Is that technically possible to do from just one subnet resource ? FYI the code I have the the aws_subnet resource is just pseudocode somewhat :slight_smile:. If using for_each is easier to achieve that, then of course that’s possible as well.

locals {
  vpc_cidrs = {
    egress = cidrsubnet(local.root_cidr, 8, 0)
    shared = cidrsubnet(local.root_cidr, 8, 1)
    # starting from the last cidr to keep special cidrs and team account cidrs grouped
    datascience = cidrsubnet(local.root_cidr, 8, 255)
  }
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  for_each = local.vpc_cidrs
  name                        = each.key
  cidr                        = each.value
  azs                         = local.azs
  enable_flow_log             = true
  tags = {
    Name = each.key
  }
}

resource "aws_subnet" "private" {

  count = length(module.vpc)
  cidr_block        = cidrsubnet(module.vpc.*.vpc_cidr_block[count.index) ,3 , count.index )
  availability_zone = element(local.azs, count.index)
  vpc_id            = element(module.vpc.*.vpc_id[count.index], count.index)
  tags = {
    Name = "${module.vpc.*.name[count.index)}-private"
  }
}

Hi @edwdev,

The splat operator .* expects the value to its left to be a list, but (as with resource for_each) the for_each feature makes the module appear as a map.

It looks like your goal is to create one subnet for each instance of the module, so a concise way to write that down is to use the module itself as for_each in the subnet configuration:

resource "aws_subnet" "private" {
  for_each = module.vpc # one subnet per VPC instance

  cidr_block        = cidrsubnet(each.value.vpc_cidr_block, 3, ???)
  availability_zone = local.azs[???]
  vpc_id            = each.value.vpc_id[count.index]
  tags = {
    Name = "${each.value.name}-private"
  }
}

However, this has some problems in your case because you were trying to use count.index to compute some results that don’t come directly from the module, which I replaced by ??? placeholders above. The problem with that is that the module instances are not in any specific order, so they don’t have incrementing indices to assign. Therefore you’ll need to find a new approach for deciding these, but I don’t know how the rest of this module fits together so I’m not sure what best to suggest here. One answer would be to change local.azs to be a map with the same keys as in local.vpc_cidrs and then you could index it with each.key. I don’t have a similar idea for the cidrsubnet call, because you really do need a consistent incrementing integer for that.