Terraform operations

Terraform State and Remote Backends

Protect Terraform state, prevent concurrent writes, separate environments, and recover state without unsafe manual editing.

How this page is maintained

Written for learners, checked against the sources below, and reviewed every quarter. Last reviewed July 27, 2026.

Short answer

Terraform state records the mapping and selected attributes connecting configuration to remote objects. A remote backend centralizes state and may provide locking, access control, encryption, and version history. State can contain sensitive data, so restrict it, separate environments, back it up, and modify it only through reviewed Terraform state operations.

Who this is for: Teams moving Terraform from individual local use to shared, automated infrastructure management across environments.

  • Treat state as sensitive operational data even when configuration contains no visible secret.
  • Give each environment a clear backend and state boundary with locking and least-privilege access.
  • Use supported import, move, and remove operations with backups instead of editing state JSON by hand.

Know what state is for

Terraform uses state to bind each resource address in configuration to a remote object and to retain attributes needed for planning. Without that mapping, it cannot reliably know that a block represents an existing resource. State also supports dependency calculations and performance when remote APIs cannot answer every question efficiently.

State may include resource identifiers, addresses, rendered values, and provider-returned data. Marking an output sensitive hides it from routine display but does not remove it from state. Avoid passing secrets through Terraform when a service can reference an external secret directly, and protect every state snapshot as confidential according to its contents.

Choose and configure a backend

A backend determines where state is stored and how operations interact with it. Teams generally need durable remote storage, encryption, restricted access, version recovery, and locking or run serialization. Backend capabilities differ, so verify current documentation and test lock behavior. A storage bucket alone is not a complete collaboration process if two applies can race.

Backend credentials should come from secure runtime configuration rather than hardcoded files, because some backend settings can be copied into local metadata or plans. Limit read access as well as write access. Automation may need apply permission, while most developers can work through plan and review paths without direct state mutation.

Separate environments and ownership

Production and test infrastructure should not share one state file merely because they use the same module. Separate state reduces blast radius and creates clearer credentials and approvals. Directory, workspace, account, and backend conventions must make the active environment visible in every plan and run record.

Split state along operational ownership and change cadence, but account for dependencies between states. Publish only necessary outputs through approved mechanisms and avoid circular relationships. Many tiny states create coordination overhead, while one enormous state makes every change broad and gives all operators excessive access. Record why each boundary exists.

Move and recover state safely

Use declarative moved blocks or supported state commands when resource addresses change. Import existing resources deliberately and verify the resulting plan. Before any state migration, stop concurrent writers, back up the source, identify exact addresses, rehearse on non-production state, and establish how to restore the previous snapshot.

If a lock remains after a crashed run, confirm that no operation is active before using the supported lock-release procedure. Never force a lock release merely because a wait is inconvenient. For suspected state loss or corruption, preserve current files and backend versions, restrict writes, and follow an incident runbook. Manual JSON editing should be an exceptional, specialist-reviewed last resort.

Move local state into a team backend

One engineer holds the only state file for shared staging infrastructure on a laptop.

  1. Inventory the state contents, confirm the real remote resources, and pause all Terraform writes for that environment.
  2. Create an approved remote backend with encryption, access policy, version recovery, and supported locking or serialized runs.
  3. Back up the local state securely, configure the backend without embedded credentials, and use Terraform's initialization migration flow.
  4. Run a refresh-based plan expecting no infrastructure changes, test lock contention, and only then enable the team automation path.
Result: The team gains controlled shared state and verifies that migration changed storage location without changing managed infrastructure.

State boundary register

Maintain one entry per independently managed Terraform state.

  • Environment, owning team, configuration root, managed responsibilities, and excluded resources.
  • Backend type, exact location, encryption, version retention, lock method, and recovery owner.
  • Read, plan, apply, migration, and emergency access roles with approval requirements.
  • Sensitive content assessment, external secret references, audit logs, and retention policy.
  • Migration procedure, backup evidence, lock test, restore exercise, and last no-change verification.

Common mistakes

  • Emailing a state file to a teammate without considering the credentials and values it may contain.
  • Sharing one production state between unrelated teams to avoid defining ownership boundaries.
  • Forcing a state lock open without proving that the original apply has stopped.

Try one

A resource was renamed in configuration and the plan now proposes one deletion and one creation. How can state preserve the existing object safely?

A strong answer verifies that the old and new addresses represent the same remote object, then uses a reviewed moved block or supported state move with a backup and no concurrent writers. It expects a no-change plan afterward. It does not manually edit JSON or apply the destroy-and-create proposal to test the theory.

Sources

Learn this with a tutor

Tell LearnLive what you already know and what you need to do with terraform state and backends.

Build this course