Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Terraform By James Joyner IV · · 11 min read

Rotating OpenTofu State Encryption Keys Without Locking Yourself Out

OpenTofu state encryption is easy to turn on and easy to brick during a key rotation. Here's the two-phase fallback method that rotates keys with zero downtime and a safe rollback.

  • #terraform
  • #ai
  • #opentofu
  • #state
  • #encryption

Turning on OpenTofu state encryption is a five-minute job that every guide covers. Rotating the key — which any real key-management policy requires on a schedule, and which becomes urgent the moment you suspect exposure — is where teams get hurt. The failure mode isn’t a bad plan; it’s permanently losing the ability to decrypt your own state.

The good news: there’s a clean, two-phase pattern built on the fallback block that rotates keys with zero downtime. The bad news: get the direction wrong or retire the old key too early and you brick your state. Let’s do it carefully.

The mental model: primary plus fallback

OpenTofu’s encryption config lets you define a method (used to encrypt new writes) and a fallback (used only to decrypt existing state). The whole rotation hinges on using both at once during the transition:

  • New key as primary — encrypts everything written from now on.
  • Old key as fallback — still able to decrypt the state that was written before the rotation.

You bring the new key online as primary, keep the old key as a decrypt-only fallback, run once to re-encrypt, then drop the fallback. Miss the direction — old as primary, new as fallback — and you’ve accomplished nothing.

Phase 0: a decryptable baseline

Before touching the config, take a backup you can actually read, and confirm you can read it:

tofu state pull > state-backup-$(date +%Y%m%d).json
# Sanity-check it's real, readable JSON
head -c 200 state-backup-*.json

An irrecoverable mistake during rotation means lost state. This backup is your rollback. Keep it safe and confirm it’s decryptable before you proceed.

Phase 1: stage the new key as primary, old as fallback

Update the terraform { encryption { ... } } block so the new key provider is the primary method and the old key is the fallback:

terraform {
  encryption {
    key_provider "pbkdf2" "new_key" {
      passphrase = var.new_passphrase
    }
    key_provider "pbkdf2" "old_key" {
      passphrase = var.old_passphrase
    }

    method "aes_gcm" "new_method" {
      keys = key_provider.pbkdf2.new_key
    }
    method "aes_gcm" "old_method" {
      keys = key_provider.pbkdf2.old_key
    }

    state {
      method   = method.aes_gcm.new_method   # new = primary (encrypts writes)
      fallback {
        method = method.aes_gcm.old_method   # old = fallback (decrypts existing)
      }
    }
  }
}

With this in place, OpenTofu can still read the state encrypted under the old key, and any new write is encrypted under the new key.

Phase 2: force the re-encryption pass

The state isn’t re-encrypted just because you changed the config — you have to trigger a write. A plan that results in a state write, or an explicit state push, rewrites the state under the new primary method:

tofu plan
tofu apply   # or any operation that writes state

After this, the state on the backend is encrypted with the new key. Confirm it’s now decryptable with the new key by running a fresh tofu plan and watching it succeed.

Phase 3: retire the old key

Only once every state file that shared the old key has been re-encrypted do you remove the fallback:

state {
  method = method.aes_gcm.new_method
  # fallback block removed
}

Run once more to confirm everything works with the new key alone. This is the step that needs the most discipline in a multi-workspace setup.

The multi-workspace trap

If several workspaces or state files share the encryption key — which is common — you cannot drop the fallback until all of them have gone through Phase 2. Remove the fallback while one straggler is still encrypted under the old key, and that straggler is now unreadable, because nothing can decrypt it anymore.

This is the single most common way teams lose state during rotation: they migrate the workspaces they remember, retire the old key, and discover a forgotten one too late. Keep a per-workspace checklist and don’t remove the fallback until every box is ticked.

Let AI sequence it, then rehearse

The encryption-block syntax and the phase ordering are exactly the kind of error-prone detail worth handing to an AI assistant — and exactly the kind you must rehearse against non-production state before trusting. A prompt like:

I run OpenTofu with PBKDF2 passphrase state encryption across four workspaces sharing one key. Walk me through rotating to a new passphrase using the fallback method: the encryption block for the transition phase, the re-encryption step, the final single-key block, and a per-workspace checklist. Include a rollback from a pulled backup.

A good answer hands you the staged blocks above plus:

Do not remove the fallback until all four workspaces have been re-encrypted. If any step fails, restore from state-backup-*.json with tofu state push. Rehearse on a throwaway workspace first.

That rehearsal instruction is the whole point — the AI drafts the sequence, you prove it on disposable state before pointing it at anything real. Our OpenTofu state encryption key rotation prompt is built around producing both phases and the rollback together, and our guide on encrypting state at the source covers the initial setup.

The rules that keep state recoverable

  • Keep a verified decryptable backup throughout the rotation.
  • New key is primary, old key is fallback — never the reverse.
  • Re-encrypt every workspace before retiring the old key.
  • Rehearse on disposable state first.

State encryption is only as safe as your ability to rotate keys without losing access. Treat rotation as a recoverable, rehearsed operation with a fallback and a backup, and it’s a non-event. Treat it as a quick config edit and it’s the day you lose your state. For more on protecting Terraform and OpenTofu state, browse our Terraform category.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.