Locals, Collections, and Functions
Scenario: Tagging rules are copied into twelve resources and gradually diverge across teams.
Locals name reusable expressions within a module; they are not mutable variables. Functions such as merge, lookup, try, can, coalesce, flatten, setproduct, and string/path helpers transform values. For-expressions can filter and reshape collections. Prefer a sequence of named locals over one dense expression. Understand whether a value is ordered and whether its keys are stable before feeding it to for_each.
Analogy: Locals are labeled preparation bowls in a kitchen. They make each transformation inspectable; one enormous expression is a blender with an opaque lid.
A worked configuration
locals {
required_tags = { ManagedBy = "terraform", Env = var.environment }
effective_tags = merge(var.extra_tags, local.required_tags)
enabled_names = [for n, cfg in var.services : n if cfg.enabled]
}
Place required tags last in merge if callers must not override them; reverse the order when caller overrides are intentional. These tiny ordering choices encode governance and deserve tests or validation.
Note: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it.
Goal: Reinforce this lesson in the tf-count-for-each Terraform lab. Open/labs/terraformand choose slugtf-count-for-each; the lab runs real Terraform against the offline FakeCloud provider.