ignore_changes and Shared Ownership

Scenario: An autoscaler legitimately adjusts a server fleet's capacity every few minutes in response to real load, and every single Terraform plan afterward proposes shrinking it right back down to whatever fixed number is written in the configuration.

ignore_changes, set inside a lifecycle block, tells Terraform: consider this specific argument's value when the resource is first created, but afterward, stop treating any live difference on that one field as something to reconcile. This is the correct, deliberate tool for exactly the scenario above - a case of genuinely shared ownership, where some other system (an autoscaler, a manual runbook that legitimately tunes one setting) is meant to actively control a specific field going forward, and Terraform should stop fighting it over that one attribute.

The honest trade-off: every field you add to ignore_changes becomes permanently invisible to Terraform's normal drift detection (Module 5) - which is exactly the point when the ownership genuinely is shared, but also exactly the risk if you reach for it too broadly. Scope it to the single narrowest attribute that actually needs to be shared (desired_capacity, not the whole resource), write a comment naming which external system owns that field and why, and treat ignore_changes = [all] - ignoring literally everything about a resource - as a red flag reserved for carefully bounded, temporary transitions, never a permanent convenience.

Analogy: Two pilots cannot both hold the same physical control at the same time without fighting each other for it. The sane arrangement is to explicitly assign the autoscaler ownership of the throttle for that one specific control, while Terraform continues to own the aircraft's overall configuration - each system has a clearly scoped, non-overlapping area of authority.

A worked configuration

lifecycle {
  ignore_changes = [desired_capacity]
}

Because every ignored field silently drops out of your normal plan-time visibility, it deserves independent monitoring outside Terraform - a field that's meant to be autoscaler-owned capacity could just as easily start drifting because of a security misconfiguration or unexpected cost change, and Terraform will now never mention it. Periodically revisit every ignore_changes entry in a codebase and confirm the shared-ownership arrangement it represents is still actually true and still actually needed - these tend to accumulate and outlive the reason they were originally added.

Common mistakes in production

Goal: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it. Reinforce this lesson in the tf-lifecycle-safety Terraform lab. Open /labs/terraform and choose slug tf-lifecycle-safety; the lab runs real Terraform against the offline FakeCloud provider.