Terraform newbie here.
I'd like to iterate a list using for_each
, but it seems like the key and value are the same:
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 = toset(var.vpc_cidrs)
cidr_block = each.value
enable_dns_hostnames = true
tags = { Name = "Company0${each.key}" }
}
I'd like the tag Name to be "Name" = "Company01"
and "Name" = "Company02"
but according to terraform apply
, I get:
"Name" = "Company010.0.0.0/16"
and "Name" = "Company010.1.0.0/16"
What am I missing?
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) }
for_each
will use a map of cidr_block
to index
mapping as returned by for
cidr_block
can then just use the each.key
valuetags
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) }
}
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) }
}
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}" }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With