Terraform / Sensitive data, governance, and recovery / Lesson 15
Drift and three-way review
Compare declared intent, stored state, and observed reality before deciding whether to restore, adopt, or investigate a difference.
On this page
Lesson goals
- Distinguish configuration change from out-of-band change and missing objects.
- Explain refresh-only review without treating it as infrastructure repair.
A difference needs a source and an owner
Configuration describes intended management, state records stored bindings and attributes, and provider reads supply observations of actual objects. These views can differ for legitimate external automation, emergency changes, unauthorized modification, provider normalization, or stale evidence. Calling every difference drift without identifying its source can produce the wrong remedy. Establish who owns the attribute, what changed, when it changed, and which view is authoritative for the decision. A planโs observations are scoped to its execution context and time, not a permanent real-time truth.
Refresh-only mode reviews state observations
Refresh-only planning is intended to review changes to state and outputs based on observed remote objects, rather than propose configuration-driven infrastructure changes in that mode. Applying such a plan would still write state, so it is an operational action requiring authorization. It does not rewrite source configuration to match reality and is not a backup or automatic recovery procedure. The command below is a non-runnable illustration only; it can still access configured providers and backends if executed elsewhere.
terraform plan -refresh-only
No plan is run here. The mode changes the review question, not the need to know workspace ownership, execution identity, backend, provider permissions, and sensitive artifact handling. It does not make external reads inert or authorize state updates.
Separate changed intent from changed observation
The fixed dictionaries below model unchanged configuration with a different observed replica count. A real provider can normalize values, ignore configured fields, or report incomplete information, so the model cannot choose actual Terraform actions. It demonstrates the three-way reasoning boundary only. The owner might restore the configured value, intentionally adopt an approved external change, or investigate a policy incident. Those choices have different source, state, and infrastructure implications and must not be reduced to blindly accepting every new observation.
configured = {'replicas': 2, 'name': 'atlas-api'}
stored = {'replicas': 2, 'name': 'atlas-api'}
observed = {'replicas': 3, 'name': 'atlas-api'}
drift = sorted(k for k in stored if stored[k] != observed.get(k))
print('observed_difference=' + ','.join(drift))
print(f'configuration_changed={configured != stored}')
observed_difference=replicas
configuration_changed=False
Only replicas differs between stored and observed data, while configured and stored records match. No API, state file, refresh, or plan is consulted. The output does not establish whether the external change was authorized or which provider action would follow.
Absence is different from a changed attribute
If a managed object is reported missing, normal planning may propose creation according to the configuration and provider contract. Before treating that as routine repair, confirm the selected account, region, permissions, object id, and state. A lookup denied by permissions or performed in the wrong context can resemble absence. Also determine whether deletion was an approved lifecycle decision, an incident, or evidence of duplicated ownership. Recreating an object can change identity, retained data, dependencies, and external consumers even when its friendly name remains the same.
Reconcile through an explicit change decision
A controlled response records the observed difference, relevant ownership rule, intended source update or restoration, risk, and verification. ignore_changes may be appropriate for explicitly shared ownership, but silencing every difference hides useful evidence. State snapshots and saved plans remain sensitive and time-bounded. Changes can occur between review and execution, so serialize cooperating writers and re-evaluate when the approved context changes. Drift management is an ongoing ownership process, not a one-time command that guarantees the configuration, state, and external world can never diverge again.
Common errors and fixes
Every observed change is accepted into state without review.
- Why it happens
- Observation was treated as approved desired intent.
- How to fix it
- Establish ownership and authorize adoption or restoration explicitly.
- Prevent it next time
- Keep three-way evidence and decision history for meaningful differences.
A wrong account lookup is diagnosed as deleted infrastructure.
- Why it happens
- Provider target and access context were not verified.
- How to fix it
- Confirm identity, permissions, location, and stored object binding first.
- Prevent it next time
- Record target context with every planning and observation artifact.
Refresh-only is expected to update source files.
- Why it happens
- State-observation review was confused with configuration authoring.
- How to fix it
- Make approved configuration changes separately and review their resulting actions.
- Prevent it next time
- Name which view each operation reads or changes.
Check your understanding
1. Which view changed in the offline replica example?
Show worked solution
Observed reality differs from the stored teaching record; configuration remains equal to the stored record. That identifies the shape of the discrepancy, not its legitimacy. Determine the attribute owner and the actual event before choosing whether to restore configuration intent or adopt an approved external decision.
2. Why can recreating a missing object be more than restoring a name?
Show worked solution
A new object can have another immutable id, empty data, changed network attachment, or consumers still referencing the old identity. Review the resourceโs recovery semantics and data plan. A matching label does not prove the original state, dependencies, or business behavior were recovered.
Key takeaways
- Separate source changes, stored evidence, and provider observations.
- Choose adoption, restoration, or incident response from ownership and evidence.