--- id: BB-SPEC-OA12Z7YV type: spec title: Cloudflare R2 OpenTofu State --- # Cloudflare R2 OpenTofu State ## Intent Make private Cloudflare R2 storage authoritative for this repository's OpenTofu state. Remove dependence on one workstation's local state. ## Scope - Migrate the current root-module state. - Define one unambiguous bucket and object key. - Support normal `tofu init`, plan, and apply workflows. - Define backup, recovery, and credential handling. ## Behavior - Every operator uses the same remote state. - Concurrent mutation is rejected before either writer can corrupt or overwrite state. - Backend failure stops the operation; OpenTofu never silently falls back to local authoritative state. - Migration preserves state identity, resource addresses, and outputs without changing infrastructure. - A clean checkout can initialize the backend using operator-supplied configuration and credentials. ## Constraints - The R2 bucket and state object are private. - Credentials are least-privilege, external to Git, and absent from OpenTofu state. - State remains plaintext secret material regardless of transport or storage encryption. - Backend storage lifecycle does not depend on the state stored inside it. - Migration retains an independent recovery copy until remote operation and restoration are verified. - Local state files cease being authoritative after migration and are not committed or synchronized. ## Acceptance - A clean checkout initializes against the intended R2 bucket and key without repository-held credentials. - Existing state migrates once with no lost resource addresses, changed lineage, or infrastructure mutation. - A post-migration `tofu plan` contains no backend-induced infrastructure changes. - A second concurrent mutation attempt is blocked. - Unauthenticated state reads and writes fail. - The operator can restore usable state after accidental object loss or overwrite using the documented recovery path. - Subsequent plan and reviewed saved-plan apply operations use R2 state exclusively.