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 of cidr_block to index mapping as returned by for
  • the cidr_block can then just use the each.key value
  • and in the tags also use format() on each.value to have a two digit with leading zeros of the index

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) }
}

Tags:

Terraform