Build an isolated receipt environment with a disposable archive, two worker groups, a remote state backend that supports locking, and a second configuration representing a receiving team. Use synthetic credentials. Record provider and module versions, lock-file changes, current state addresses, object inventory, expected owner, and a baseline plan before each phase. A test passes on observed state and remote objects, not a successful command exit alone.
Project: hand off Terraform-managed infrastructure without a replacement surprise
Adopt and replace
Create the archive outside Terraform, then import it under exactly one state address. Compare configuration with encryption, retention, and access settings; reject a post-import plan that changes them unexpectedly. Reorder the worker-group map and confirm stable instance addresses. Rename one key with a reviewed address move, then test a provider upgrade separately from the module version change. Trigger a worker replacement with quota for overlap, observe both generations, and prove traffic moves before old capacity disappears. Repeat with insufficient quota and verify the old generation remains available.
Receipt infrastructure acceptance gates
Provider: selected version and package checksums reviewed
Module: exact approved version recorded separately
Import: one object, one active state owner, no surprise update
Replacement: quota, names, traffic, and rollback proven
Lock: abandoned writer verified before own lock is released
Secrets: saved plan and state readers audited
Keys: reordered map produces no address churn
Ignored field: external controller and alert named
Handoff: old state forgets object; receiving owner adopts itRecover and transfer
Interrupt a test run while it holds the state lock. Verify the runner has stopped, preserve state, release only that run's abandoned lock, and replan against remote inventory. Inspect a saved plan and state snapshot for the synthetic credential; tighten access and retention before continuing. Let an autoscaler change only the worker group's desired capacity, then show that an unrelated security change still appears in the plan. Finally transfer the archive to the receiving configuration with an explicit state-removal plan, a freeze, and an adoption check. Abort if either configuration plans destruction or both claim the same object.
Cost and verification
Measure peak overlap capacity, state lock wait, provider refresh time, snapshot retention, and the gap between old-owner release and new-owner adoption. A cleaner plan is not enough: confirm actual object policy, customer traffic, and owner inventory. Record who can read state, who can apply it, and how a failed handoff is reversed without creating a second writer.
Common Mistakes
- Do not use a provider lock file as evidence that modules are pinned.
- Do not force-unlock an active run.
- Do not delete a resource block when the intent is to keep its object.
Connected lessons
- Terraform provider locks: review the executable dependency
- Terraform import: adopt one existing object under one state owner
- Terraform replacement: prove old and new can coexist
- Terraform state locks: distinguish a stale lease from an active writer
- Terraform state secrets: redaction is not removal
- Terraform collection keys: keep resource identity stable through reorderings
- Terraform ignore_changes: name the second owner of every ignored field
- Terraform state removal: hand off an object without deleting it
- DevOps projects
