← All insights
ENGINEERING JOURNAL / Infrastructure as Code

Terraform for_each: Keep Resource Keys Stable

Prevent avoidable resource churn by choosing stable for_each map keys. Review address changes separately from edits to each resource's configuration values.

Terraform for_each: Keep Resource Keys StableTerraform for_each: Keep Resource Keys Stable — conceptual 3D-style vector showing Business identity, Stable map key, Resource address, Editable values, Planned operation.. Conceptual teaching illustration; connections show the investigation flow rather than a vendor deployment topology.CLOUVENIX / INFRASTRUCTURE AS CODETerraform for_each: Keep Resource Keys Stable01Business identity02Stable map key03Resource address04Editable values05Planned operationConceptual investigation flow / Terraform for_each: Keep Resource Keys Stable
Terraform for_each: Keep Resource Keys Stable — conceptual 3D-style vector showing Business identity, Stable map key, Resource address, Editable values, Planned operation.
TOPICENGINEERING NOTES
01

Context

Terraform resource instances have addresses, and for_each uses a map key or set member as part of that address. A key is therefore an identity decision, not just a convenient label. If a key changes, Terraform can see one instance disappearing and another appearing even when a human thinks the same business object was merely renamed.

Before starting, identify the managed collection, current state addresses, desired change, and the object's true stable identifier. You need the correct workspace and an ordinary review branch. Initial state listing and planning are read-only with respect to infrastructure; do not apply a plan that unexpectedly replaces established resources.

02

1. Inspect the existing identity model

terraform workspace show
terraform state list
terraform plan

Compare instance addresses with the source collection. Look for keys derived from list positions, mutable display names, generated IDs, or concatenated fields that frequently change. Determine which edits should update an existing object and which genuinely represent removal and creation.

Do not assume converting a list to a set preserves every business meaning. Sets remove duplicates and have no positional order. If two intended objects have the same string, a set cannot represent them as separate instances.

03

2. Use a map with deliberate stable keys

An explicitly illustrative example manages harmless built-in records:

locals {
  destinations = {
    billing_api = {
      display_name = "Billing endpoint"
      timeout      = 10
    }
    catalog_api = {
      display_name = "Catalog endpoint"
      timeout      = 15
    }
  }
}

resource "terraform_data" "destination" {
  for_each = local.destinations
  input    = each.value
}

The keys identify logical destinations, while values contain editable configuration. Changing Billing endpoint to another display name should not require changing billing_api. Real remote resources may still replace when immutable arguments change; stable keys prevent address churn, not every provider-driven replacement.

04

3. Review the plan by instance address

Make one representative value-only edit in the review branch and inspect the plan. Confirm that the same instance address remains. Then review any intentional key change separately. If an existing collection already uses unstable identities, stop before applying an automatic conversion and plan an explicit address migration under the team's established refactoring procedure.

Keep keys non-sensitive. Terraform exposes instance identity in output, so a credential or private customer identifier is a poor key even if it would be unique. Keys also need to be determinable during planning; remote generated values are unsuitable as the identity of newly planned instances.

05

Diagnose collection-related churn

Plan evidenceLikely causeNext correction
Many instances shift after one list removalPosition-derived identityModel explicit logical keys
Rename becomes delete plus create at new addressMutable field used as keySeparate identity from display data
Duplicate items disappear after conversionSet deduplicationUse unique map keys for distinct objects
Key cannot be determined before applyRemote-generated identityUse caller-known logical keys

Review the resource's own replacement reason as well. A stable address paired with an immutable remote argument change is different from an avoidable address change. Mixing them makes migration reviews harder to understand.

06

Verify and keep an identity contract

Run validation and a fresh plan after the reviewed correction. Confirm the intended instance count and addresses, then verify that unrelated objects remain unaffected. For a migration, retain the reviewed before-and-after mapping and follow the separate state-address change workflow.

Document what each key means, who may change it, and how retired identities are handled. Add identity stability to module review whenever a new for_each collection is introduced. Monitor plans for unexpectedly broad removal or replacement rather than treating a successful language validation as proof of safe instance identity.

Explore Clouvenix terraform automation for implementation and operational handover.

Technical reference

for_each reference, meta-arguments and named resource values.