Run this before a backend holds production state for the first time: before
terraform init -migrate-state moves an existing state into it, or before the
first apply of a greenfield stack that declares it. Run it again after any
change to the bucket policy, the key policy or the lock table while the backend
is in service.
This is the gate, not the review. The quarterly review of a backend already in service — whether the recovery layers exist, whether anyone has restored from them, who can read the file — is the separate state readiness checklist. The question here is narrower: is this thing safe to write to yet.
Why this is a gate and not a review
Two of the controls on this list are not retroactive, which is the whole reason the checklist sits at this point in the timeline rather than three months later.
Versioning records writes made after it was enabled. Turn it on next quarter and the history begins next quarter; every write before that is gone, including the one you will want.
Default encryption applies to objects written after it was configured. Objects already in the bucket stay as they were written, so a bucket that reports SSE-KMS today can still be holding a plaintext state file from last month.
A third is retroactive but undetectable, which is worse. A backend with no lock
table, or a table whose partition key is not LockID, behaves exactly like a
working one until two applies overlap for the first time — which may be months
after anybody stopped looking, and which announces itself as a state file that
lost somebody else changes rather than as an error.
Everything else on the list is ordinary least-privilege work that a later review would find. These three are the ones a later review inherits rather than fixes.
What a failure means
A critical finding is a backend that will accept production state and then
either fail to give it back, or hand it to somebody who should not have it.
None of them is expensive to fix at this point — the bucket is empty, the key
policy has no dependents, nobody is blocked — and all of them get an order of
magnitude more expensive once the backend is load-bearing.
The warn items are about the migration being reversible and legible
afterwards. They cost an hour each on the day and they are what turns a bad
cutover into an inconvenience.
Access this needs
Read access to S3, KMS, DynamoDB and IAM in the account holding the backend, a checkout of the configuration, and a shell on the CI runner for one item.
Three items write, and they are the price of proving the thing works: the pre-migration copy, the no-op apply, and the two-shell lock test. Schedule the gate in a window where a no-op apply against this configuration is acceptable. Nothing else here changes anything.
Where the evidence goes
Attach the command output to the change record for the migration, not to the repository. Three items are attested rather than commanded — the single operator, the old-backend retention, and the review record itself — and each needs the name of the person who confirmed it. Two more are commanded but not decided by the command: the bootstrap ownership and the closing deny both print something a person still has to read.
Record the location of the pre-migration copy explicitly and separately. It is the one artefact on this list that becomes urgent and unreconstructable at the same moment.
Sign-off
- Operator running the migration: ________________ Date: ___________
- Platform owner: ___________ Date: ___________
- Security owner (bucket, key and IAM items): ___________ Date: ___________