Bird
Raised Fist0
Terraformcloud~10 mins

For_each for map-based instances in Terraform - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - For_each for map-based instances
Define map variable
↓
Start for_each loop
↓
Iterate over each map key-value pair
↓
Create resource instance using key and value
↓
Repeat for all map entries
↓
End loop with all instances created
Terraform reads a map variable, then loops over each key-value pair to create a resource instance for each entry.
Execution Sample
Terraform
variable "servers" {
  type = map(string)
  default = {
    web = "10.0.0.1"
    db  = "10.0.0.2"
  }
}

resource "aws_instance" "example" {
  for_each = var.servers
  ami      = "ami-123456"
  instance_type = "t2.micro"
  private_ip = each.value
}
Creates one AWS instance per map entry, using the map key as instance name and value as private IP.
Process Table
StepMap KeyMap ValueResource Instance CreatedInstance Private IP
1web10.0.0.1aws_instance.example["web"]10.0.0.1
2db10.0.0.2aws_instance.example["db"]10.0.0.2
3---All map entries processed, loop ends
💡 All map entries processed, no more keys to iterate
Status Tracker
VariableStartAfter 1After 2Final
each.key-webdb-
each.value-10.0.0.110.0.0.2-
resource count0122
Key Moments - 2 Insights
Why does Terraform use the map key as the instance identifier in the resource?
Terraform uses the map key as the unique identifier to create separate resource instances, as shown in execution_table rows 1 and 2 where aws_instance.example["web"] and aws_instance.example["db"] are created.
What happens if the map is empty?
If the map is empty, the for_each loop does not run any iterations, so no resource instances are created. This is implied by the exit_note in the execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the private IP of the instance created at step 2?
A10.0.0.1
B10.0.0.2
Cami-123456
Dt2.micro
💡 Hint
Check the 'Instance Private IP' column at step 2 in the execution_table.
At which step does Terraform finish creating all instances from the map?
AStep 3
BStep 2
CStep 1
DStep 4
💡 Hint
Look at the exit_note and the last row in the execution_table.
If the map had three entries instead of two, how would the resource count change in variable_tracker after the last iteration?
AIt would be 2
BIt would be 1
CIt would be 3
DIt would be 0
💡 Hint
Refer to the 'resource count' row in variable_tracker and how it increments per iteration.
Concept Snapshot
Terraform for_each with map:
- Use for_each = var.map to loop over map entries
- each.key is map key, each.value is map value
- Creates one resource per map entry
- Resource instances named by map keys
- Useful for dynamic multiple resource creation
Full Transcript
This visual execution shows how Terraform uses for_each with a map variable to create multiple resource instances. It starts by defining a map with keys and values. Then, Terraform loops over each key-value pair. For each pair, it creates a resource instance named by the key and uses the value for configuration, such as private IP. The execution table tracks each step, showing the key, value, resource created, and IP assigned. The variable tracker shows how each.key, each.value, and resource count change with each iteration. Key moments clarify why keys are used as identifiers and what happens if the map is empty. The quiz tests understanding of instance IPs, loop completion, and resource count changes. This method helps create multiple similar resources efficiently using map data.

Practice

(1/5)
1. What does for_each do when used with a map in Terraform?
easy
A. Creates resources only for the first key in the map
B. Deletes all resources in the map
C. Combines all map entries into a single resource
D. Creates one resource for each key-value pair in the map

Solution

  1. Step 1: Understand the role of for_each with maps

    for_each iterates over each key-value pair in a map to create multiple resources.
  2. Step 2: Recognize resource creation behavior

    Each key-value pair results in one resource instance, using each.key and each.value inside the resource block.
  3. Final Answer:

    Creates one resource for each key-value pair in the map -> Option D
  4. Quick Check:

    for_each with map = one resource per pair [OK]
Hint: Remember: for_each maps keys to separate resources [OK]
Common Mistakes:
  • Thinking for_each merges all map entries into one resource
  • Assuming for_each deletes resources
  • Believing for_each only uses the first map key
2. Which of the following is the correct syntax to use for_each with a map in a Terraform resource?
easy
A. resource "aws_instance" "example" { for_each = { key1 = "val1", key2 = "val2" } }
B. resource "aws_instance" "example" { for_each = ("key1", "key2") }
C. resource "aws_instance" "example" { for_each = "key1" }
D. resource "aws_instance" "example" { for_each = ["one", "two"] }

Solution

  1. Step 1: Identify valid for_each types

    for_each accepts a map or set of strings, but here we focus on map usage.
  2. Step 2: Check syntax correctness

    resource "aws_instance" "example" { for_each = { key1 = "val1", key2 = "val2" } } uses a map with key-value pairs correctly inside curly braces, which is valid Terraform syntax.
  3. Final Answer:

    resource "aws_instance" "example" { for_each = { key1 = "val1", key2 = "val2" } } -> Option A
  4. Quick Check:

    Map syntax with curly braces = correct for_each [OK]
Hint: Use curly braces for maps in for_each [OK]
Common Mistakes:
  • Using square brackets for maps instead of curly braces
  • Passing a single string instead of a map
  • Using parentheses which are invalid here
3. Given the Terraform snippet:
variable "servers" {
  default = {
    web = "10.0.0.1"
    db  = "10.0.0.2"
  }
}

resource "aws_instance" "example" {
  for_each = var.servers
  ami           = "ami-123456"
  instance_type = "t2.micro"
  tags = {
    Name = each.key
    IP   = each.value
  }
}

What will be the value of the tag Name for the instance with IP 10.0.0.2?
medium
A. web
B. 10.0.0.2
C. db
D. example

Solution

  1. Step 1: Map keys to IP addresses

    The map has keys 'web' and 'db' with values '10.0.0.1' and '10.0.0.2' respectively.
  2. Step 2: Match IP to key

    The IP '10.0.0.2' corresponds to the key 'db', so the tag Name will be 'db'.
  3. Final Answer:

    db -> Option C
  4. Quick Check:

    each.key for IP 10.0.0.2 = db [OK]
Hint: Match IP value to map key for Name tag [OK]
Common Mistakes:
  • Confusing key and value in the map
  • Using IP as the Name tag instead of the key
  • Assuming static tag values
4. What is wrong with this Terraform resource using for_each on a map?
resource "aws_instance" "example" {
  for_each = { "one" = "10.0.0.1", "two" = "10.0.0.2" }
  ami           = "ami-123456"
  instance_type = "t2.micro"
  tags = {
    Name = each.value
  }
  count = 2
}
medium
A. Using both for_each and count together causes an error
B. The map syntax is invalid
C. Missing each.key in tags
D. AMI ID is incorrect

Solution

  1. Step 1: Check resource meta-arguments

    Terraform does not allow using both for_each and count in the same resource block.
  2. Step 2: Identify the error cause

    The presence of count = 2 alongside for_each causes a configuration error.
  3. Final Answer:

    Using both for_each and count together causes an error -> Option A
  4. Quick Check:

    for_each and count cannot coexist [OK]
Hint: Never mix for_each and count in one resource [OK]
Common Mistakes:
  • Thinking map syntax is wrong
  • Believing missing each.key causes error
  • Assuming AMI ID is the problem
5. You have a map of server roles and IPs:
servers = {
  app1 = "10.0.1.1"
  app2 = ""
  app3 = "10.0.1.3"
  app4 = null
}

You want to create AWS instances only for servers with valid IPs using for_each. Which expression correctly filters the map to exclude empty or null IPs?
hard
A. for_each = var.servers
B. for_each = { for k, v in var.servers : k => v if v != "" && v != null }
C. for_each = { for k, v in var.servers : k => v if v == "" || v == null }
D. for_each = [ for v in var.servers : v if v != "" ]

Solution

  1. Step 1: Understand filtering with for expressions

    Use a for expression with an if condition to filter out empty strings and null values from the map.
  2. Step 2: Check each option

    for_each = { for k, v in var.servers : k => v if v != "" && v != null } correctly filters keys where value is neither empty string nor null, producing a valid filtered map for for_each.
  3. Final Answer:

    for_each = { for k, v in var.servers : k => v if v != "" && v != null } -> Option B
  4. Quick Check:

    Filter map with if condition to exclude empty/null [OK]
Hint: Filter map with for and if to exclude empty/null [OK]
Common Mistakes:
  • Not filtering out empty or null values
  • Using list comprehension instead of map
  • Filtering for empty/null instead of excluding them
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard