Switch from using count/element and a data source to for_each

I’m looking to switch from count to for_each but I’m having trouble with the following.

The following is an example of what I’m currently using and takes advantage of the wrap feature with element.

data "aws_availability_zones" "available" {
  state = "available"
}

resource "aws_instance" "example" {
  count                  = length(var.example_ips)
  subnet_id              = element(module.vpc.private_subnets, count.index)
  private_ip             = element(var.example_ips, count.index)
}

Any ideas on how to recreate this with for_each? I’ve tried the code below however a change of order to var.example_ips still results in recreating the instances because I’m still looking at the index to loop through subnet_id.

resource "aws_instance" "example" {
  for_each = { for ip in var.example_ips : ip => index(var.example_ips, ip) }
  subnet_id              = element(module.vpc.private_subnets, each.value)
  private_ip = each.key
}

Hi @johnmerrill,

I’m having trouble inferring your original design intent from the examples you’ve shared. Could you try to state the problem you are trying to solve in English first, and then how that problem mapped on to the code examples you’ve shared? For example, I started to try to formulate a sentence like “for each of the subnets, select an example IP address from that subnet and associate it with an instance”, but I don’t know what an “example IP address” is and how they relate to your private subnets.

Let’s say that var.example_ips is a set with 3 IPs and the region I’m deploying into only has 2 availability zones or I only want to use 2 of those zones. In my original example, I’m saying

“for each IP in var.example_ips, create an ec2 instance with that given IP and create it in an existing subnet with the same index value.”

It then knows that it has to loop back around to index 0 of the subnets because there is not an index 2 to use to create the 3rd ec2 instance.

I’d like to accomplish the same thing but remove referencing an index so the order is not important. I’d also like to continue getting the availability zones from the data source so I do not have to map those to IPs.

data "aws_availability_zones" "available" {
  state = "available"
}