How to Use Terraform's 'for_each', with Examples (2023)

ReleaseHub sponsored this post.

How to Use Terraform's 'for_each', with Examples (1)

Terraform is one of the most popular infrastructure as code (IaC) tools. With Terraform, you can write code that defines the infrastructure components you want and the configuration for them. You then execute that code, and Terraform will make sure that your infrastructure is set up the way you defined it. This means either creating new components or responding with “All of these are already created.”

Sounds easy, right?

In reality, Terraform code can be quite complicated. That’s especially likely when you want to do some advanced stuff, like iterating over a certain number of resources.

For example, let’s say you want to create multiple virtual machines with the same configuration. For cases like that, in Terraform you can use for_each. In this post, you’ll learn what that is as well as how and when to use it.

Infrastructure as Code with Terraform

If you’re new to Terraform, before we move on, you need to understand what it actually is.

Modern environments are quite complex, and you have a few options when you want to add, change or destroy some components of your infrastructure. If you’re on the cloud, you can go to your cloud provider web UI and execute any necessary action from there. You can also use CLI or even write some scripts yourself and call your cloud provider API.

There are, however, some limitations to all these options. Clicking in the web UI doesn’t scale. And you don’t want to create dozens of different services every time you need a new environment.

Using CLI or writing your own scripts is a step forward. But why not take two steps forward instead and use a dedicated infrastructure-as-code tool?

One of the biggest advantages of using Terraform is that it will keep the state of your infrastructure saved.

Terraform is one such tool. You write Terraform-specific code defining how you want your infrastructure to look. Then you execute Terraform and everything is taken care of for you. It’s a highly efficient and scalable way of creating infrastructure.

Also, one of the biggest advantages of using Terraform is that it will keep the state of your infrastructure saved. Therefore, it will always try to have your infrastructure in sync. So once you execute Terraform, it will only create, change or destroy resources that aren’t in sync with the saved state.

Terraform Meta-Arguments

Before we dive into explaining how for_each works, let’s briefly talk about what it actually is.

In Terraform, we mainly talk about resource blocks and module blocks. For example, when you want to create a virtual machine, you need to define a resource block with configuration details of that machine. Within the resource and module block, you can also use one of the five so-called meta-arguments. These are special instructions that aren’t part of the resource configuration per se, but they instruct Terraform to do some action in relation to that resource. And one of these instructions is for_each.

As I already mentioned, the main purpose of the for_each meta-argument is to create multiple instances of a resource. So, as you can imagine, it’s quite useful to know.

It’s also worth mentioning that for_each has been added to Terraform in version 0.12. But I hope you’ve already upgraded to Terraform 1.x anyway.

Multiple Resources

To understand better what purpose for_each serves, let’s see how you could achieve the same outcome in Terraform without using for_each.

The outcome we’re talking about is deploying multiple copies of the same resource. So, let’s take virtual machines, for example.

Normally, to deploy more than one virtual machine, you’d have to specify multiple resource blocks, like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

resource "google_compute_instance" "vm1" {

name = "vm1"

machine_type = "e2-small"

zone = "us-central1-a"

(...)

}

resource "google_compute_instance" "vm2" {

name = "vm2"

machine_type = "e2-medium"

zone = "us-central1-a"

(...)

}

resource "google_compute_instance" "vm3" {

name = "vm3"

machine_type = "f1-micro"

zone = "us-central1-a"

(...)

}


Seems like a lot of duplicated code, doesn’t it? That’s exactly where for_each can help.

Instead of duplicating all that code for each virtual machine, you can define your resource once and provide a map or a set of strings to iterate over.

Take a look at the example. This is how achieving the same results as above would look with for_each:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

resource "google_compute_instance" "vm" {

for_each = {

"vm1" = "e2-small"

"vm2" = "e2-medium"

"vm3" = "f1-micro"

}

name = each.key

machine_type = each.value

zone = "us-central1-a"

(...)

}


As you can see, we defined the configuration parameters that differ per virtual machine as key-value pairs in the for_each block and left the parameters that are the same for each VM in the resource block. Then, we accessed the key-value pair by special keywords each.key and each.value.

What if you want to pass more than just two (key and value) parameters? For example, what if you want to also parameterize the zone in the above example? You can simply change the value to a map, as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

resource "google_compute_instance" "vm" {

for_each = {

"vm1" = { vm_size = "e2-small", zone = "us-central1-a" }

"vm2" = { vm_size = "e2-medium", zone = "us-central1-b" }

"vm3" = { vm_size = "f1-micro", zone = "us-central1-c" }

}

name = each.key

machine_type = each.value.vm_size

zone = each.value.zone

(...)

}


You can pass as many parameters in the value as you want. Then in the actual resource configuration, you can reference them with each.value.<parameter_key>.

To keep your code clean and have the ability to reuse values for different resources, you can even extract the actual parameters into a variable:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

locals {

virtual_machines = {

"vm1" = { vm_size = "e2-small", zone = "us-central1-a" },

"vm2" = { vm_size = "e2-medium", zone = "us-central1-b" },

"vm3" = { vm_size = "f1-micro", zone = "us-central1-c" }

}

}

resource "google_compute_instance" "vm" {

for_each = local.virtual_machines

name = each.key

machine_type = each.value.vm_size

zone = each.value.zone

(...)

}

‘for_each’ Versus ‘count’

If you’re not new to Terraform, you may have used another meta-argument that seems like the same thing: count. And while count also lets you create multiple instances of the same resource, there’s a difference between count and for_each. The latter isn’t sensitive to changes in the order of resources.

A common issue with count is that once you delete any resource other than the last one, Terraform will try to force replace all resources that the index doesn’t match.

You don’t have that problem with for_each because it uses the key of a map as an index. You can’t use both count and for_each on the same resources, but why would you anyway?

Are there any drawbacks to for_each? Yes.

How to Use Terraform's 'for_each', with Examples (2)

Release makes it easy and cost effective to create cloud native full-stack environments with data, on-demand. These environments are being used for previewing and QA’ing features in the dev workflow. Release enables engineering organizations deploy more code, faster.

Learn More

The latest from ReleaseHub

Limitations of ‘for_each’

While for_each is pretty straightforward to use, there are some limitations you should be aware of. First of all, the keys in your for_each map block must have a known value. Therefore, for example, they can’t be generated on the fly by functions (like bcrypt or timestamp). They also can’t refer to resource-specific attributes that are provided by a cloud provider, like a cloud resource ID. Another limitation is the fact that you can’t use sensitive values as arguments for for_each. Basically, when using for_each, you need to directly specify the values.

Using ‘for_each’ is relatively easy, but you need a solid understanding of how it works to get the most benefits from it.

Summing Up and Learning More

for_each is probably one of the most commonly used Terraform meta-arguments. Modern environments usually consist of multiple instances of resources for high-availability and scalability reasons. Using for_each is relatively easy, but you need a solid understanding of how it works to get the most benefits from it. It also has its own limitations.

In this article, you learned how for_each works and got some tips on how to use it efficiently. Now, you can try to play around with it yourself or look into other meta-arguments.

Terraform at Scale

ReleaseHub’s environment as a service is an easy-to-use, highly scalable service that leverages Terraform to create snapshots of even the most complex environments and automatically manages their creation and teardown as part of your development lifecycle.

Dawid Ziolkowski has 10 years of experience as a network/systems engineer at the beginning, DevOps in between, cloud native engineer recently. He has worked for an IT outsourcing company, a research institute, telco, a hosting company and a consultancy company,... Read more from Dawid Ziolkowski

FAQs

What is the use of For_each in Terraform? ›

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.

What does For_each => mean in Terraform? ›

Terraform's for_each meta-argument allows you to configure a set of similar resources by iterating over a data structure to configure a resource or module for each item in the data structure. You can use for_each to customize a set of similar resources that share the same lifecycle.

Can we use count and For_each together in Terraform? ›

Version note: Module support for count was added in Terraform 0.13, and previous versions can only use it with resources. Note: A given resource or module block cannot use both count and for_each . Hands-on: Try the Manage Similar Resources With Count tutorial.

What is the difference between dynamic block and For_each in Terraform? ›

In Terraform, dynamic blocks let you create nested blocks inside a resource based on a variable. Instead of creating a resource for each item in a map, as the for_each attribute does, dynamic blocks create nested blocks inside a resource for each item in a map or list.

What is the difference between For_each and transform? ›

for_each is a non-modifying algorithm; transform is a mutating algorithm. for_each ignores the operation's return value; transform assigns the return value to successive elements in the output range. for_each returns a copy of the function object; transform returns an iterator to the end of the output range.

What are three types of variables that exist within Terraform? ›

Lists, maps, and objects are the three most common complex variable types. They all can be used for their specific use cases.

What is the difference between Terraform count and For_each? ›

When to use for_each instead of count. If the resources you are provisioning are identical or nearly identical, then count is a safe bet. However, if elements of the resources change between the different instances, then for_each is the way to go.

How to set path variable for Terraform? ›

Update the path environment variable to include the folder where your Terraform executable is located.
  1. Go to the Control Panel.
  2. Click System.
  3. On a Windows 10 system, click Advanced system settings. ...
  4. Click Environment Variables near the bottom of the window. ...
  5. In the System variables pane, click Path and then click Edit.

How do you pass values to variables in Terraform? ›

The first way you can pass variables inside your child modules would be to define a variables.tf file on your main module and a terraform. tfvars. Then you should also define a variables.tf file inside each module and contain the definition of each module.

How to pass multiple values to a single variable in Terraform? ›

Once you have one or more . tfvars files created, you can then use the -var-file flag to pass in the name of the file for Terraform to pull in for passing Input Variables to the Terraform command. Multiple -var-file flags can be used on the same Terraform command to pass in multiple .

How many types of loops are there in Terraform? ›

Below is a summary of the three main looping constructs found within the HashiCorp Configuration Language (HCL) used by Terraform.

How do you call a Terraform module multiple times? ›

for_each to call terraform module multiple times
  1. Keep your Terragrunt Architecture DRY. Keep your Terragrunt Architecture DRY. Motivation. Using include to DRY common Terragrunt config. Using exposed includes to override common configurations. ...
  2. Before, After, and Error Hooks. Before and After Hooks. Tflint hook. Configuration.

What are two complex types in Terraform? ›

There are two categories of complex types: collection types (for grouping similar values), and structural types (for grouping potentially dissimilar values).

What is the difference between local and input variable in Terraform? ›

You can use locals to give a name to the result of any Terraform expression, and re-use that name throughout your configuration. Unlike input variables, locals are not set directly by users of your configuration. In this tutorial, you will use Terraform to deploy a web application on AWS.

What is the difference between Tfvars and locals in Terraform? ›

How do locals differ from variables and hard-coded values in Terraform? Locals values are not set by the user input or values in . tfvars files, instead, they are set 'locally' to the configuration (hence the name). Instead of hardcoding values, local values can produce a more meaningful or readable result.

What is the difference between STD :: copy and STD :: For_each? ›

std::for_each is a more generic algorithm. With std::copy you specify that you aim to copy from one range to another. Some would say that's easier to understand and therefore makes the code easier to maintain.

What is the difference between STD For_each and range based loop in C++? ›

std::for_each returns the functor that has been used internally in the loop, so it provides a clean mechanism to gather some information concerning the elements in the sequence. The range based for loop is just a loop, so any state that is to be used outside of the loop has to be declared outside of that scope.

What is the difference between STD transform and STD for each? ›

std::for_each ignores the return value of the function, and guarantees order of execution. std::transform assigns the return value to the iterator, and does not guarantee the order of execution.

What are the two main components of Terraform? ›

Terraform has two important components: Terraform Core and Terraform Plugins. Terraform Core oversees the reading and interpolation of resource plan executions, resource graphs, state management features and configuration files. Core is composed of compiled binaries written in the Go programming language.

What are 3 different ways to pass variables to a Terraform run? ›

Different ways to use Terraform variables
  • Interactive Input – terraform variables. Just don't give default value. ...
  • Command-line variables. You can pass command line variables at the time of apply action. ...
  • Variable file .tfvars. ...
  • Environment variables.
Jan 2, 2022

What is the difference between map and object in Terraform? ›

map(object) is just a map of objects, similar to how map(string) is a map of strings. You can also have things like map(map(string)) which is a map of maps of strings for example. map(object) isn't doing some sort of type conversion.

How many layers can you Terraform? ›

This allows collaboration. As there is one state file per layer and per workspace, each team member can make changes to different layers without conflicting with coworkers' modifications to other layers. You can terraform apply two layers simultaneously without worrying about the state lock, which is fantastic.

How do I run Terraform in multiple environments? ›

Terraform Workspaces

You can create a workspace for each environment and switch between them using the terraform workspace command. This allows you to maintain separate states for each environment and makes it easier to manage multiple environments within a single configuration.

How many operations Terraform can perform concurrently? ›

The amount of memory to allocate to a Terraform run and the number of concurrent runs are the primary elements in understanding capacity above the base services. By default, Terraform Enterprise allocates 512 MB of memory to each Terraform run, with a default concurrency of 10 parallel runs.

How do you override a variable in terraform command line? ›

Overriding variables in Terraform via the command line

The first method we will look at is to use an input variable at the command line this is the simplest of methods and most commonly used for ad-hoc overrides, here we simply add a -var 'variable_name=”value” as an option for the terraform plan or apply command.

How do I set multiple Path variables? ›

To add multiple path values under the PATH variable separate your values with a semi-colon. To be clear, this is only true for certain variables. For instance adding another path to the TEMP variable would just break things.

How do I find my environment variable Path? ›

Select Start, select Control Panel. double click System, and select the Advanced tab. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it.

Can we have multiple variable files in terraform? ›

We can defined any number of variable in same way. let see it with example so create variable.tf file with below content. create hello-variable.tf file with below content.

Can you output a variable in terraform? ›

The terraform output command is used to extract the value of an output variable from the state file.

How can I load input data from a file in terraform? ›

You can use the file function in Terraform. This file function reads the contents of a file at the given path and returns them as a string.

How to pass multiple variables to API? ›

Pass Multiple Parameters in URL in Web API
  1. First create a Web API Application. Start Visual Studio 2012. ...
  2. In the view add some code. In the "Solution Explorer". ...
  3. Now return to the "HomeController" Controller and create a new Action Method. ...
  4. Now create a View as in the following. ...
  5. Now execute the application.
Dec 11, 2020

How do you merge two objects in Terraform? ›

merge Function

merge takes an arbitrary number of maps or objects, and returns a single map or object that contains a merged set of elements from all arguments. If more than one given map or object defines the same key or attribute, then the one that is later in the argument sequence takes precedence.

How do you pass a variable from one Yaml to another? ›

To pass params between yml files in Azure DevOps you have to specify a path to the template (the file you want to pass the param across to) and give the parameter a value. Then in the second file also declare the parameter.

What are the 3 types of loop? ›

In Java, there are three types of loops: for, while, and do-while. The for loop is used for a known number of iterations, the while loop is used for an unknown number of iterations based on a condition, and the do-while loop is similar to the while loop, but the code block is executed at least once.

What is the difference between a set and a list in Terraform? ›

To help understand why this is the case, let's take a look at the difference between a Terraform List and a Set. So the difference between a List and Set is that Set values are all guaranteed to be unique. Also, Sets do not have any particular ordering. With a map, the key naturally provides uniqueness already.

Can we have 2 providers in Terraform? ›

We can't write two or more providers with the same name i.e. two AWS providers. If there's any such need the terraform has provided a way to do that which is to use alias argument. Note: A provider block without an alias argument is the default configuration for that provider.

Can I call same module twice Terraform? ›

With Terraform, you can put your code inside of a Terraform module and reuse that module in multiple places throughout your code. Instead of having the same code copied and pasted in the staging and production environments, you'll be able to have both environments reuse code from the same module: This is a big deal.

Can two resources have the same name Terraform? ›

terraform-aws-resource-naming

For most of the resources, AWS does not allow us to create multiple resources with the same name. That is the reason why we need to make them unique.

How do you declare an object in Terraform? ›

To declare an object in Terraform, we'll create three files: vars.tf. outputs.tf.
...
As shown in the file, the following values are assigned to the variables within the object previously declared:
  1. Type : triangle.
  2. s_one :1.
  3. s_two : 2.5.
  4. s_three :2.5.
  5. description : “this is a triangle”

How does Terraform handle dependencies? ›

Terraform uses this dependency information to determine the correct order in which to create the different resources. To do so, it creates a dependency graph of all of the resources defined by the configuration. In the example above, Terraform knows that the EC2 Instance must be created before the Elastic IP.

What are the different dependency types in Terraform? ›

There are 2 types of resource dependencies in Terraform — Implicit and Explicit. In the first example, you will find depends_on which creates an explicit dependency of AWS s3 bucket on the AWS EC2 instance.

What is the difference between resource and output in Terraform? ›

Resource instances managed by Terraform each export attributes whose values can be used elsewhere in configuration. Output values are a way to expose some of that information to the user of your module.

What is the difference between string and number in Terraform? ›

The Terraform language uses the following types for its values: string : a sequence of Unicode characters representing some text, like "hello" . number : a numeric value. The number type can represent both whole numbers like 15 and fractional values like 6.283185 .

What is the difference between output and variables in Terraform? ›

Input Variables serve as parameters for a Terraform module, so users can customize behavior without editing the source. Output Values are like return values for a Terraform module. Local Values are a convenience feature for assigning a short name to an expression.

What is the difference between import and data resource in Terraform? ›

Data sources vs importing a resource

In both cases, you get information about the resource made available inside your Terraform configuration. However, the key difference is that if you import a resource then you now manage it. That means: If you terraform destroy your configuration, that resource will be destroyed.

What is the difference between coalesce and try in Terraform? ›

coalesce takes any number of arguments and returns the first one that isn't null or an empty string. All of the arguments must be of the same type. Terraform will try to convert mismatched arguments to the most general of the types that all arguments can convert to, or return an error if the types are incompatible.

What is the use of for in Terraform? ›

A for expression creates a complex type value by transforming another complex type value. Each element in the input value can correspond to either one or zero values in the result, and an arbitrary expression can be used to transform each input element into an output element.

What are the advantages of For_each C++? ›

for_each is more generic.
...
Here are some reasons:
  • It seems to hinder readability just because you're not used to it and/or not using the right tools around it to make it really easy. ...
  • It allows you to write an algorithm on top of for_each that works with any iterator.
  • It reduces the chance of stupid typing bugs.
Jan 12, 2010

What is the difference between for each and for in Terraform? ›

First off, for is a Terraform expression, while for_each is a meta-argument that can be applied to resources and modules. What's the difference? A meta-argument controls Terraform's behavior when creating, destroying, or replacing resources.

What are the most useful Terraform commands? ›

Basic Terraform commands
  • Prepare Cloud Shell.
  • Prepare the directory.
  • Apply the changes.
  • Reformat.
  • Validate.
  • Delete changes.
  • Specify the project ID.
  • What's next.

When should you not use Terraform? ›

The reason to avoid using `terraform import` is very pragmatic: it's tricky to do correctly, especially for more complicated resources. Terraform is designed to create resources and manage resources it creates. The import functionality works, but during the process, it's very easy for settings to be changed.

Why would you use C instead of C++? ›

Picking C over C++ is a way for developers and those who maintain their code to embrace enforced minimalism and avoid tangling with the excesses of C++. Of course, C++ has a rich set of high-level features for good reason.

What makes C better than C++? ›

The significant difference between C and C++ is an Object-oriented language that gives the advantages of data security, scalability, better performance, rich built-in functions and so much more.

Why would you choose C rather than C++? ›

Compared to C++, C is the simpler and ultimately faster programming language. C is procedural and does not support classes and objects, meaning it has less functionality than C++. This allows you to spend more time focusing on what you can do with C's libraries, especially at the OS level.

What is the difference between STD :: copy and STD :: for_each? ›

std::for_each is a more generic algorithm. With std::copy you specify that you aim to copy from one range to another. Some would say that's easier to understand and therefore makes the code easier to maintain.

What is the difference between range based loop and for loop? ›

The difference between a for loop and a range based for loop is roughly analogous to the difference between goto and a for loop. Former is a more generic control flow, while the latter is more structured. Every range based loop can be written as a for loop and every for loop can be written as a goto.

What is the difference between normal for loop and advanced for loop? ›

Difference between for loop and advanced for loop in Java

i.e the counter is always increased by one, whereas in for loop you can change the step as per your wish e.g doing something like i=i+2; to loop every second element in an array or collection. 3) The enhanced for loop can only iterate in incremental order.

References

Top Articles
Latest Posts
Article information

Author: Gregorio Kreiger

Last Updated: 17/01/2024

Views: 5499

Rating: 4.7 / 5 (57 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Gregorio Kreiger

Birthday: 1994-12-18

Address: 89212 Tracey Ramp, Sunside, MT 08453-0951

Phone: +9014805370218

Job: Customer Designer

Hobby: Mountain biking, Orienteering, Hiking, Sewing, Backpacking, Mushroom hunting, Backpacking

Introduction: My name is Gregorio Kreiger, I am a tender, brainy, enthusiastic, combative, agreeable, gentle, gentle person who loves writing and wants to share my knowledge and understanding with you.