Objective
By the end of this lab, you will have:
- Created a configuration with multiple instances using count.
- Created a configuration with multiple instances using for_each.
- Verified that count is identity-fragile.
- Verified that for_each is identity-stable.
Requirements
- A Linux or macOS workstation with shell access.
- The Terraform CLI 1.9.x or later installed.
Scenario
You have a configuration that needs to create multiple files. You are choosing between count and for_each. The choice has implications for refactoring and state stability.
Tasks
Task 1: Create the working directory
mkdir -p ~/rb-count-vs-foreach
cd ~/rb-count-vs-foreach
mkdir -p count foreach
cd ~/rb-count-vs-foreach
Task 2: Create the count configuration
Create count/main.tf:
terraform {
required_version = ">= 1.9.0"
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.5"
}
}
}
resource "local_file" "readme" {
count = 3
filename = "${path.module}/count-${count.index}.txt"
content = "File from count, index ${count.index}\n"
}
Task 3: Apply the count configuration
cd count
terraform init
terraform apply
Verify:
ls count-*.txt
cat count-0.txt
Task 4: Modify the count
Change the count from 3 to 2:
resource "local_file" "readme" {
count = 2
...
}
Apply:
terraform apply
Verify:
ls count-*.txt
The count-2.txt file is destroyed. The remaining files are
count-0.txt and count-1.txt.
This is the count antipattern: changing the count can destroy real-world resources.
Task 5: Create the for_each configuration
Create foreach/main.tf:
terraform {
required_version = ">= 1.9.0"
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.5"
}
}
}
resource "local_file" "readme" {
for_each = toset(["a", "b", "c"])
filename = "${path.module}/foreach-${each.key}.txt"
content = "File from for_each, key ${each.key}\n"
}
Task 6: Apply the for_each configuration
cd ../foreach
terraform init
terraform apply
Verify:
ls foreach-*.txt
cat foreach-a.txt
Task 7: Modify the for_each
Remove the key “b” from the set:
resource "local_file" "readme" {
for_each = toset(["a", "c"])
...
}
Apply:
terraform apply
Verify:
ls foreach-*.txt
The foreach-b.txt file is destroyed. The foreach-a.txt and
foreach-c.txt files are unchanged.
This is the for_each advantage: changing the keys only affects the changed keys.
Task 8: Add a new key
Add the key “d” to the set:
resource "local_file" "readme" {
for_each = toset(["a", "c", "d"])
...
}
Apply:
terraform apply
Verify:
ls foreach-*.txt
The foreach-d.txt file is created.
Validation
The lab is successful if:
- The count configuration created 3 files and then destroyed 1.
- The for_each configuration created 3 files, destroyed 1, and created 1.
Expected Outcome
After the count experiment:
count-0.txt
count-1.txt
After the for_each experiment:
foreach-a.txt
foreach-c.txt
foreach-d.txt
Cleanup
cd ~/rb-count-vs-foreach
rm -rf count foreach
What You Learned
You learned the count vs for_each trade-off:
countis identity-fragile. Changing the count can destroy real-world resources.for_eachis identity-stable. Changing the keys only affects the changed keys.- For stateful resources, use
for_eachwith a stable semantic key. - For ephemeral resources,
countis fine.