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
- Create the destination project and workspace in StackShip.
- 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.
- Recreate your variables. Copy sensitive values from your secret manager — most platforms, including StackShip, never let you read them back.
- Set up and verify credential profiles.
- 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:
- Open the destination workspace and select the CLI access tab.
- Under Purpose, choose State migration and pick an expiry.
- 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.
-
Back up the current state:
cp terraform.tfstate terraform.tfstate.pre-stackship -
Add the
cloudblock to your configuration. -
Run
tofu initand confirm when OpenTofu asks to migrate existing state. -
Check the result:
tofu state pull > stackship-state.json tofu plan -refresh=false
Move from Terraform Cloud or another backend
-
While the old backend is still configured, lock the source workspace and export its state:
tofu state pull > source-state.json -
In a fresh directory, check out your configuration with the StackShip
cloudblock. Don’t copy the old.terraformdirectory. -
Initialize and push the exported state:
tofu init -input=false tofu state push source-state.json -
Check the result with
tofu state pullandtofu 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
- Make sure only StackShip can write to the state from now on.
- Run a plan and investigate every unexpected change.
- Check the policy result.
- 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.