Skip to content

Migrate state to StackShip

Move existing OpenTofu or Terraform state from local files or Terraform Cloud into a StackShip workspace.

Updated View as Markdown

Migrate state with ordinary tofu commands; there’s no special import tool. Migrate one workspace at a time, and stop all writes to the old backend first.

Before you start

  1. Create the destination project and workspace in StackShip.
  2. Pick the same OpenTofu version you use today, or a compatible newer one. StackShip runs OpenTofu only; if you applied with Terraform, confirm your state and provider lock file work with that OpenTofu version first.
  3. Recreate your variables. Copy sensitive values from your secret manager — most platforms, including StackShip, never let you read them back.
  4. Set up and verify credential profiles.
  5. Write down the source state’s outputs and resource addresses so you can compare them afterwards.

Get a migration token

For an interactive migration, use tofu login stackship.run. For a scripted one, create a scoped token:

  1. Open the destination workspace and select the CLI access tab.
  2. Under Purpose, choose State migration and pick an expiry.
  3. Select Create token and save the token in your secret manager. It’s shown only once.

The token can read, lock, and write state for this workspace only. Pass it to tofu through an environment variable:

export TF_TOKEN_stackship_run='<token>'

Configure the cloud block

Copy the block from CLI access. It uses the workspace’s Cloud workspace name, which may differ from its display name:

terraform {
  cloud {
    hostname     = "stackship.run"
    organization = "your-org-slug"

    workspaces {
      name = "network-foundation"
    }
  }
}

Use the cloud block, not the generic http backend.

Move local state

Start in the directory that holds your terraform.tfstate.

  1. Back up the current state:

    cp terraform.tfstate terraform.tfstate.pre-stackship
  2. Add the cloud block to your configuration.

  3. Run tofu init and confirm when OpenTofu asks to migrate existing state.

  4. Check the result:

    tofu state pull > stackship-state.json
    tofu plan -refresh=false

Move from Terraform Cloud or another backend

  1. While the old backend is still configured, lock the source workspace and export its state:

    tofu state pull > source-state.json
  2. In a fresh directory, check out your configuration with the StackShip cloud block. Don’t copy the old .terraform directory.

  3. Initialize and push the exported state:

    tofu init -input=false
    tofu state push source-state.json
  4. Check the result with tofu state pull and tofu plan -refresh=false.

State files can be up to 100 MB.

Verify the migration

Compare outputs and resource addresses with the values you recorded. A clean tofu plan should show no unexpected changes.

Migrating into an empty workspace gives the state a new lineage and restarts the serial at 1. Your resources and outputs are unchanged. Keep your backup until you’ve completed a clean plan and apply in StackShip.

What migration doesn’t copy

Migration doesn’t bring across:

  • variables and their values;
  • cloud credentials and trust relationships;
  • GitHub connections and source settings;
  • policies (Sentinel policies must be rewritten in Rego);
  • members and teams; or
  • run and audit history.

Set these up in StackShip before your first apply.

Cut over

  1. Make sure only StackShip can write to the state from now on.
  2. Run a plan and investigate every unexpected change.
  3. Check the policy result.
  4. Approve and apply.

Never let two systems apply to the same infrastructure.

Moving out

Download any state version from the workspace’s State tab, or run tofu state pull with the cloud block.

Next steps

Navigation

Type to search…

↑↓ navigate↵ selectEsc close