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/terraform and choose slug tf-count-for-each; the lab runs real Terraform against the offline FakeCloud provider.