Terraform get list index on for_each
Found an easy solution using the index function:
tags = { Name = "Company0${index(var.vpc_cidrs, each.value) + 1}" }
There is also another way of achieving the wanted result without using index()
:
change the following three lines:
for_each = { for idx, cidr_block in var.vpc_cidrs: cidr_block => idx}
cidr_block = each.key
tags = { Name = format("Company%02d", each.value + 1) }
- the
for_each
will use a map ofcidr_block
toindex
mapping as returned byfor
- the
cidr_block
can then just use theeach.key
value - and in the
tags
also useformat()
oneach.value
to have a two digit with leading zeros of theindex
Full example will be:
provider "aws" {
profile = "default"
region = "us-east-1"
}
variable "vpc_cidrs" {
default = ["10.0.0.0/16", "10.1.0.0/16"]
}
resource "aws_vpc" "vpc" {
for_each = { for idx, cidr_block in var.vpc_cidrs: cidr_block => idx}
cidr_block = each.key
enable_dns_hostnames = true
tags = { Name = format("Company%02d", each.value + 1) }
}
You could use the count
function and use the index to do this:
provider "aws" {
profile = "default"
region = "us-east-1"
}
variable "vpc_cidrs" {
type = list(string)
default = ["10.0.0.0/16", "10.1.0.0/16"]
}
resource "aws_vpc" "vpc" {
count = length(var.vpc_cidrs)
cidr_block = var.vpc_cidrs[count.index]
enable_dns_hostnames = true
tags = { Name = "Company0${count.index}" }
}
When for_each
is used with a set, each.key
and each.value
are the same.
To generate strings like "Company01", "Company02", etc., you need the index of each CIDR block in the list. One way to do this is to create a local map using a for
expression like:
locals {
vpc_cidrs = {for s in var.vpc_cidrs: index(var.vpc_cidrs, s) => s}
}
resource "aws_vpc" "vpc" {
for_each = local.vpc_cidrs
cidr_block = each.value
enable_dns_hostnames = true
tags = { Name = "Company0${each.key}" }
}
As a bonus, you can use the format function to build the zero-padded name string:
resource "aws_vpc" "vpc" {
...
tags = { Name = format("Company%02d", each.key) }
}