Contents

Terraform ForEach Loop

ForEach loop explained

Website Visitors:

If you want to perform same operation multiple times, you have to use a loop. In Terraform, you can use Foreach loop to do the same. In this tutorial, we’ll explain what is Terraform foreach loop and how to use it.

When you run a deploy command, terraform will deploy an instance or a resource only once in your infrastructure. If you want to deploy a group of instances or create multiple resources, you can create them using  count and for_each.

If a resource or module block includes a for_each argument whose value is a map or a set of strings, Terraform will create one instance for each member of that map or set.

Tip
Version note: for_each was added in Terraform 0.12.6. Module support for for_each was added in Terraform 0.13; previous versions can only use it with resources.

Basic Syntax

for_each is a meta-argument defined by the Terraform language. It can be used with modules and with every resource type.

The for_each meta-argument accepts a map or a set of strings, and creates an instance for each item in that map or set. Each instance has a distinct infrastructure object associated with it, and each is separately created, updated, or destroyed when the configuration is applied.

Map:

1
2
3
4
5
6
7
8
resource "azurerm_resource_group" "rg" {
  for_each = {
    a_group = "eastus"
    another_group = "westus2"
  }
  name     = each.key
  location = each.value
}

Set of strings:

1
2
3
4
resource "aws_iam_user" "the-accounts" {
  for_each = toset( ["Todd", "James", "Alice", "Dottie"] )
  name     = each.key
}

Child module:

1
2
3
4
5
6
# my_buckets.tf
module "bucket" {
  for_each = toset(["assets", "media"])
  source   = "./publish_bucket"
  name     = "${each.key}_bucket"
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# publish_bucket/bucket-and-cloudfront.tf
variable "name" {} # this is the input parameter of the module

resource "aws_s3_bucket" "example" {
  # Because var.name includes each.key in the calling
  # module block, its value will be different for
  # each instance of this module.
  bucket = var.name

  # ...
}

resource "aws_iam_user" "deploy_user" {
  # ...
}

The each Object

In blocks where for_each is set, an additional each object is available in expressions, so you can modify the configuration of each instance. This object has two attributes:

  • each.key — The map key (or set member) corresponding to this instance.
  • each.value — The map value corresponding to this instance. (If a set was provided, this is the same as each.key.)

for_each Limitations

The keys of the map (or all the values in the case of a set of strings) must be known values, or you will get an error message that for_each has dependencies that cannot be determined before apply, and a -target may be needed.

for_each keys cannot be the result (or rely on the result of) of impure functions, including uuidbcrypt, or timestamp, as their evaluation is deferred during the main evaluation step.

Sensitive values, such as sensitive input variablessensitive outputs, or sensitive resource attributes, cannot be used as arguments to for_each. The value used in for_each is used to identify the resource instance and will always be disclosed in UI output, which is why sensitive values are not allowed. Attempts to use sensitive values as for_each arguments will result in an error.

If you transform a value containing sensitive data into an argument to be used in for_each, be aware that most functions in Terraform will return a sensitive result if given an argument with any sensitive content. In many cases, you can achieve similar results to a function used for this purpose by using a for expression. For example, if you would like to call keys(local.map), where local.map is an object with sensitive values (but non-sensitive keys), you can create a value to pass to for_each with toset([for k,v in local.map : k]).

Note
A given resource or module block cannot use both count and for_each.

Suggested Article

Now that you know what is ForEach loop, continue reading about Count and Conditionals here. All other DevOps categories are listed here. Have a look at the posts as per your topic of interest.

Conclusion

In this tutorial, we’ve explained about foreach loop in Terraform and its basic usage. We’ve also demonstrated examples for all the topics that are discussed.

We hope you have learned something new in this article. Please feel free to share your thoughts about this article in the comments section below.

Your inbox needs more DevOps articles.

Subscribe to get our latest content by email.