How to export state from Spacelift before your contract ends
State and code can leave Spacelift, but run history, managed secret values, Rego policies in their current form and private worker setup do not move as files. Each stack's state can be pulled with a task that runs terraform state pull, or through external state access if your account and plan include it. Your code should already sit in Git, so the export mostly concerns state and the settings Spacelift holds for each stack. Stack settings, contexts and policies have to be recorded by hand or read through the Spacelift API. Confirm the exact export mechanics against current Spacelift documentation and your account's own settings before you plan around them.
Treat each pulled state file as sensitive, because it can contain secrets in plain text. Push every state to a bucket or backend you control, with encryption at rest and access limited to the people and pipelines that need it. Record a checksum or the state serial for each workspace at the moment of the pull, so you can show later which version you moved. Decide before the pull whether applies will be paused on each stack, since a run that changes infrastructure after the pull leaves the copied state out of date. OpenTofu can encrypt state at rest with key providers such as AWS KMS, GCP KMS or OpenBao, so decide on the key provider before the state lands in its new home.
Build an inventory of everything the stacks depend on: stack settings, contexts, environment variables, attached policies, and the secret references they use. Secret values usually cannot be read back out of Spacelift, so plan to re-enter them from your own secrets manager. In the new platform, initialize each workspace against the migrated state, following the Terrakube CLI-driven workflow documentation, and run a plan. A clean, no-change plan is the acceptance test for each workspace. If a plan proposes changes, stop and find the cause before you cut over, because a diff usually means a missing variable, a provider version mismatch or an incomplete state.
Which Spacelift data you can export and in what format
This table lists each category of Spacelift data you need before leaving, the method for pulling it out, the format it arrives in and the limits to confirm. Use it as a checklist: state is the most urgent item because it cannot be rebuilt from code alone, while settings, contexts and policies usually have to be recorded by hand or pulled through the API. Confirm every limit with Spacelift before you schedule cutover.
| Data type | Export method | Format | Limits to confirm |
|---|---|---|---|
| State per stack | Run a task that executes terraform state pull and uploads the result to your own bucket, or enable external state access and read it from your side | JSON, following the OpenTofu and Terraform state model | Confirm with Spacelift which state versions are retained and whether external state access is available on your plan |
| HCL and module code | Already held in your VCS repository, so record the branch and commit that each stack plans from and freeze it | Plain HCL and module source files in Git | Confirm which branch each stack tracks and whether any stacks use code outside the main repository |
| Stack settings and variables | Record by hand per stack, or pull through the Spacelift API once you confirm which endpoints your account can call | Text fields and key-value pairs, typically exported as JSON or a spreadsheet | Confirm the API endpoints available to your account and how sensitive variables are returned, if at all |
| Contexts and policies | Export the policy and context text where the interface allows it, or record each attachment manually | Rego policy text and context definitions, typically as plain text | Confirm the export format for contexts and policies and whether attachments can be listed programmatically |
| Run and plan history | Usually not needed for cutover, so decide whether you keep a record of recent plan outputs | Logs and plan output text as shown in the Spacelift interface | Confirm retention periods for run logs with Spacelift before relying on them as evidence |
| Cloud credentials and integrations | Document the cloud roles, VCS connections and webhooks each stack uses, since secrets are not part of a state or code export | Written inventory kept in your own system | Confirm with your security team how each credential is re-issued in the new platform |
What does not move with the state and how to rebuild it
State and configuration are only part of a Spacelift exit. Run history, secrets, policies, worker networking, source connections and audit records stay behind or need a different home in the target platform. Each card names one item, what breaks if it is missed, and how to rebuild it before the first cutover stack.
Run history and logs
Spacelift keeps the record of past plans, applies, and run logs inside its own service, and an exported state file does not carry any of it. Once you leave, you cannot pull those logs back from the old platform through the state export. Before you cut over, export or archive the logs you need for change records and incident reviews, and confirm the retention window your compliance team expects. Plan for Terrakube's run history to start empty on the first run in each workspace.
Stored sensitive variable values
Sensitive variables and secret values set in Spacelift contexts or stacks are write-only in the UI, so assume you will not read them back in plain text. Confirm with Spacelift whether any export path returns these values before you plan around one. In most cases, the value owners re-enter secrets from their own vault, such as a cloud secrets manager, and you attach them to the new Terrakube workspaces through its variable settings.
Rego policies
Spacelift policies written in Rego do not run in Terrakube unchanged, because Terrakube's extensions use OPA checks that you configure yourself. Inventory every push, plan, approval and trigger policy attached to a stack, then rewrite each one as an OPA policy and test it against saved plan JSON from a real run. Policies that depend on Spacelift-specific input fields need a translation step, and you should not assume the rule still enforces what it did before.
Private worker pools and networking
Spacelift private workers run inside your network and reach private endpoints, internal registries and on-premises systems. Those routes do not transfer. Terrakube executors need their own network path to the cloud APIs, state backend and private modules, so map every egress rule, DNS entry and firewall allowance the workers used. Test each workspace from a Terrakube executor before cutover, because a run that fails on a private endpoint may look like a provider error.
VCS and identity connections
Repository connections, webhooks, group mappings and user permissions are configured inside Spacelift and must be recreated in Terrakube. Terrakube connects to GitHub, GitLab, Bitbucket and Azure DevOps and assigns permissions by group through Dex. Recreate each VCS connection with the minimum token scope, rebuild group access on workspaces and modules, and confirm that a commit to a tracked branch starts the expected run in the new platform.
Audit trails and approvals
Spacelift's audit log records who changed stacks, approved runs and modified policies, and that history does not move with the state. If an auditor will ask about past changes, export the audit records you must keep and store them in your own log system before shutdown. In Terrakube, approvals and access changes start a new audit baseline, so document that date and link it to the migration change record.
Sequence to export state from Spacelift in order
This sequence moves each stack's state and configuration out of Spacelift in a fixed order, so that every workspace can be proven to match its source before anything is cut over. Each step ends with a check that the team can repeat later.
Freeze changes to each stack
Before exporting, pause runs that could change state for each stack you plan to move. Stop auto-deploy on the tracked branch, disable tracking where your team can do so, and ask engineers to hold manual runs and merges to the stack's repositories. The platform engineering lead or stack owner usually confirms this with the teams that use each stack. The step is done when no run is queued or in progress for the stack and the freeze is written in your migration log with a time and owner.
Record current state and configuration versions
For each stack, note the most recent state version, the latest run ID, the OpenTofu or Terraform version the stack uses, the commit it is tracking, and the backend type. Capture these in a table that the migration team can review. The output is one row per stack with its identifiers, which you will use to confirm the export later. Check the stack list in Spacelift against your inventory so no stack is missed.
Export state with a task or external access
Choose one of the two routes Spacelift supports for getting state out. Either run a task in the stack that executes
terraform state pull(or the OpenTofu equivalent) and writes the output to a file, or enable external state access for the stack and read the state from the remote backend with your own credentials. Confirm which route your Spacelift plan allows and who holds the credentials used for it. The step is done when a non-empty JSON state file exists for each stack and it parses as valid JSON.Copy state to your team's bucket
Upload each exported state file to the object storage bucket your team controls, using a per-stack path and versioning turned on so earlier copies are kept. Restrict the bucket policy to the operators of the new platform and the auditors who need access. Keep the source export on separate storage until cutover is complete. The step is done when each object is listed in the bucket with its path, size and upload time recorded in the migration log.
Record checksums and export settings
Compute a SHA-256 checksum for each state file, both at export and again after the copy in the bucket, and compare the two values. Also export the stack settings Spacelift holds for each stack: variables and their sensitivity flags, attached contexts, policy attachments, branch and path settings, and VCS connection details. Store these in a versioned repository, with secret values left out and held in your secrets manager. The check is a matching checksum for every state file and a settings record for every stack.
Export contexts and policies as source
Retrieve each context's variables and attached hooks, and each policy's source, which is written in Rego. Keep the Rego files in version control so they can be translated and reviewed when the new platform is set up. Record which policy types apply to which stacks, such as plan, approval or trigger policies. The output is a repository of policy source and a mapping of context and policy attachments to stacks, which you will use to recreate the same controls in the new platform.
Confirm access and a clean plan in the new home
Before any cutover, have the team that will operate the new platform log in with the Terraform or OpenTofu CLI and load the exported state into a test workspace. Run a plan on the unchanged configuration and confirm it reports no changes for each stack. Confirm that the operators can read the bucket and the repository of settings. Record the plan output summary and the operator sign-off per stack. Cut over a stack only after its clean plan is recorded.
How to protect exported state once it sits in your bucket
State files contain sensitive values in plain text, including database passwords, generated keys and any secret that a resource attribute held at apply time. Once terraform state pull output lands in your own bucket, the bucket policy becomes the control that matters most. Restrict read and write access to the pipeline identity and a small set of platform administrators, turn on object versioning so a bad overwrite can be rolled back, and confirm that server-side encryption at rest is enabled with a key your team controls. Treat every exported file as a production secret, and keep the same rules for backups and copies made during the migration window.
OpenTofu also offers client-side encryption of state and plan files, so the file is encrypted before it reaches any backend. Its documented key providers include AWS KMS, GCP KMS and OpenBao, along with PBKDF2 for passphrase-based setups. Client-side encryption does not replace bucket controls, but it means a copy of the bucket alone does not expose plaintext state. Decide where the keys live before you copy anything: which account or cloud project owns the KMS key, who can use it to decrypt, how key rotation works, and what happens to the old state if a key is lost. Note that encrypted state must be decryptable by every OpenTofu run that needs it, so test that path in a non-production workspace first.
Confirm your own retention and access rules before you set a lifetime for exported state and its versions. Check with your security and compliance owners how long previous state versions must be kept, who approves access to them, and how deletion is evidenced once the migration ends. Retention periods and approval steps come from your policies, not from the migration tooling, so write them down and apply them to the bucket, the key and the audit logs before the first state file is copied.
Checking that each exported stack plans clean
A stack with one state file and no inbound dependencies is the simplest case to verify. Once the state has been pushed to your own bucket and the backend block points at it, a plan in the new home should report no changes against the infrastructure it already manages. That is the clean result you are looking for. Run the first plan from a workspace with the same code revision and the same variable values you used in Spacelift, then compare the output line by line.
- Pin the versions: Use the same OpenTofu or Terraform version and the same provider lock file as the Spacelift stack, so differences come from the platform and not from the tooling.
- Check for replacements: Any
must be replacedline usually means a variable, a resource name or a backend key differs from what was in the exported state. - Watch environment variables: Values that Spacelift injected as environment variables or contexts are often missing in the new workspace, which shows up as null or default values in the plan.
- Investigate tag drift: Provider default tags or tags added by a policy in Spacelift may not exist in the new home and will appear as in-place updates.
- Confirm the lock: Verify that state locking works before any apply, since the backend that held the state in Spacelift no longer does.
Do not apply anything until a plan shows no changes for the stack you are testing.
Stacks that read other stacks through the terraform_remote_state data source, or consume their outputs, depend on the order in which states move. OpenTofu's migration guidance says configurations that share data this way typically need additional care, and it links a separate guide for that case. Plan the producer stack first, then each consumer, and confirm the outputs are identical before moving anything that reads them.
- Compare outputs: Run
tofu output -jsonon the producer in both places and diff the results before the consumer is switched. - Update backend references: A consumer that points at a Spacelift state location will fail until its
terraform_remote_stateblock refers to the new bucket and key. - Check access rights: The new bucket policy must allow each consumer's identity to read the producer's state, which is a common cause of plan failures.
- Freeze producers: Avoid applying a producer during the test window, because a consumer reading a stale output can plan a change that is not real.
- Keep the order: Verify producers before consumers and record which consumers were tested against which producer revision.
Read the migration guide linked from OpenTofu's overview before changing any terraform_remote_state block, and treat a consumer as unverified until its plan is clean.
Spacelift contexts bundle environment variables, mounted files and hooks, and its policies are written in Rego and attached at several points in a run. Neither has a one-to-one equivalent in Terrakube, so a plan can look clean while a control that used to run is now missing. Inventory each context and each policy attached to a stack, then decide what replaces it before you test.
- List attachments: Record which contexts and policies apply to each stack, including those attached through labels or inherited from parents.
- Recreate variables explicitly: Move context variables into Terrakube workspace variables and confirm each secret is marked sensitive.
- Test policy separately: Run the OPA checks in a Terrakube extension against a known-bad plan to confirm they fail as expected, rather than trusting a green run.
- Record gaps: Any Spacelift policy type without a matching Terrakube control should be logged as an open item with an owner.
- Plan with and without: Compare a plan that would violate a policy in both environments to confirm the outcome matches.
Confirm with your security or compliance owner that every policy you rely on is either reproduced or formally accepted as removed before the stack is cut over.
Testing in a fixed sequence limits the number of variables that change at once. A sensible order starts with stacks that have no dependencies and no policies, then moves to stacks that read remote state, then to stacks with contexts and policies, and finally to the most sensitive production stacks. Each step should finish with a clean plan before the next begins. This sequence is a suggested approach, and your own dependency graph may require a different order.
- Start with a non-production stack: Use a low-risk stack to prove the backend, credentials and runner work end to end.
- Run plans only at first: Keep applies disabled until every stack in the wave shows no changes.
- Compare run logs: Save the plan output from Spacelift and Terrakube for each stack so differences can be reviewed later.
- Test state locking: Start two plans against the same workspace to confirm the second one waits or fails cleanly.
- Record results: Keep a dated log of each stack, its tested revision and its sign-off, which auditors often ask to see.
For each stack, the sign-off should name who confirmed the clean plan and which open items remain.
A clean plan is not always the same as a correct migration. Drift that appears in the new home often points to something the export missed, such as a value held outside state, a provider configuration that changed, or a resource that was changed by hand. Investigate every unexpected change before accepting it, and never apply a plan to make a diff disappear without knowing its cause.
- Provider configuration: Differences in provider versions, regions or assumed roles can produce plans against the wrong account, so confirm the target before reading the diff.
- Manual changes: A resource changed in the console since the last Spacelift run will show as drift, which is a finding to report rather than a migration fault.
- Sensitive values: Values hidden in plan output may still differ, so compare the state file hash or the specific attributes you care about.
- Random and time values: Resources that generate values on each plan, such as timestamps or random suffixes, are expected to change and should be documented as such.
- Module sources: A module pulled from a different revision or registry will change resources, so check the source and version lines.
If you cannot explain a change in one sentence, treat the stack as not yet verified.
What to plan before your Spacelift contract ends
Spacelift access usually ends on a fixed date, so the work that matters happens before renewal or termination. The cards below cover the contract terms, the parallel run, the order of cutover, the records you must keep, ownership of the new platform and the retirement of old credentials.
Confirm notice and data access terms
Read the contract for the notice period, the date access stops and what Spacelift will keep or delete after that date. Ask in writing whether state, run logs and policy history remain available for export after the subscription ends. Confirm the exact notice and retention terms with Spacelift and your procurement team, since they set the deadline for every other step on this list.
Set a parallel-run window
Plan for each workspace to plan clean in Terrakube or Atlantis while Spacelift still holds the live state. Run both platforms side by side for a set period, comparing plan output against the Spacelift run for the same commit. Agree the length of this window with your change owners before you start, so it does not collide with the contract end.
Decide the cutover order
Rank stacks by dependency and risk, and move the leaves first. Stacks that feed others through remote state or shared outputs should move together, because a single stack pointing at a stale backend can produce confusing plans. Record the order in a shared plan so each cutover has a named owner and a rollback point.
Secure exported state and records
Store every exported state file, plan output, stack settings, context definition and policy in a location you control before access ends. Encrypt state at rest, restrict read access and keep a checksum or version history so you can prove what was exported and when. Once Spacelift access is gone, you cannot re-export these items through the same route.
Assign owners for the new platform
Name one owner for the state backend, one for the run platform and one for each team's workspaces and access groups. Operating Terrakube or Atlantis means someone patches the server, manages the database, rotates the identity provider configuration and reviews who can approve runs. Those duties do not transfer automatically from Spacelift, so assign them before cutover.
Schedule Spacelift credential retirement
List every API key, cloud role, VCS webhook and worker credential that Spacelift holds for your accounts. Revoke or rotate each one after its last stack has cut over, and remove Spacelift webhooks from your repositories so stale runs do not trigger. Keep the revocation dated in your change log so auditors can trace when Spacelift stopped having access.
Common questions about exporting data from Spacelift
How much effort does exporting state from Spacelift take?
The effort scales with how many stacks you run and how much each one depends on shared configuration. Pulling state for a handful of stacks with simple backends is a small task, while dozens of stacks that read other stacks' outputs, use many contexts, or attach a set of Rego policies take considerably more planning. The main drivers are the number of stacks, how many contexts and policies are attached to them, whether other configurations read data through the terraform_remote_state data source, and whether any stack uses a backend or secret source that the new platform cannot reach yet. Ask for a stack inventory with those four attributes before agreeing on scope, since that inventory is what the rest of the estimate rests on.
How long does a Spacelift state export usually take?
The timeline is set by the number of stacks to cut over, the dependencies between them, and how many review cycles your change process requires. Exporting state itself is quick for each workspace, so most of the calendar goes to recreating settings, validating that each workspace plans clean, and scheduling cutovers in an order that respects stack dependencies. Change freezes, approval windows and the availability of people who own the affected infrastructure often matter more than the technical steps. Ask for a timeline in the written scope that lists the stack groups, their dependency order and the approval steps, rather than a single overall duration.
What does our team need to provide for the export?
Your team needs to supply access and decisions, not just time. Expect to provide administrative access to Spacelift and to the cloud accounts holding the state buckets, a named owner for each stack who can confirm what it manages, and someone who can approve maintenance windows. You will also need to decide where state will live, which key provider will encrypt it, and who holds the keys. Engineers who understand the Terraform or OpenTofu code should review plan output for every workspace, because a clean plan is only meaningful when the people responsible for the infrastructure agree it reflects reality.
Can our platform team export Spacelift state without an outside partner?
Yes, a capable platform team can do the export internally, provided it has the access, time and review capacity to do it safely. The core steps are documented in the OpenTofu migration guidance, which describes backing up state and code, installing OpenTofu, initializing and verifying the configuration, and testing with a small change. The harder parts are inventorying undocumented dependencies, translating policies, and keeping production runs unaffected during cutover. Consider an outside partner when the inventory is large, when stacks depend on each other in complex ways, or when your team cannot spare people for parallel review. Compare the internal effort against a fixed-scope written quote so the trade-off is visible.
What happens to runs that are in progress during the export?
Runs that are queued or applying when you start the export should be allowed to finish before you pull state, because pulling state mid-apply can capture an inconsistent picture. Freeze new runs on the stacks being exported, confirm no run is active, then export the state and record its version. Keep Spacelift as the source of truth until the new platform has produced a clean plan for that workspace. Pending pull request runs and scheduled drift checks should also be paused or removed, so they do not write to state after the snapshot is taken. Confirm the exact freeze procedure with the team that runs your Spacelift tenant.
How do we ask for a fixed-scope quote for this export?
Ask for a written scope that lists the stacks in scope, the components to move for each (state, variables, contexts, policies, VCS connections and external dependencies), the deliverables for each stack, the acceptance check, and the client responsibilities. Ask the provider to state what is excluded, such as policy rewrites or changes to the target platform's own hosting. DeployOpen works from a written scope agreed before work starts, and it does not publish a price list, so the quote follows from that scope. Share your stack inventory early, because a quote built on an accurate inventory is far more reliable than one built on assumptions.
How do we confirm each workspace plans clean after the export?
Run a plan in the new environment against the exported state and compare its output with the last plan from Spacelift. A clean result means no changes are proposed for infrastructure that has not been edited, and any diff has a documented explanation. Use the same OpenTofu or Terraform version on both sides, and check that variables and provider credentials resolve to the same values. Keep the old plan output for comparison and record which stacks passed. Only retire the Spacelift stack after each workspace has passed this check and the owner has signed off, so you have a clear rollback path until then.
How DeployOpen scopes and delivers a Spacelift state export
DeployOpen plans and delivers state exports from Spacelift as a fixed-scope engagement inside your own cloud accounts or data centers. We start from a written inventory of stacks, state locations and access rules, then move each workspace's state to a bucket you control and confirm it plans clean in its new home.
How we scope
- Inventory every Spacelift stack, its state location and which teams can read or write it.
- Record stack settings, attached contexts, policies and VCS links that must be recreated outside Spacelift.
- Agree in writing which stacks export first, the target bucket, encryption approach and the verification each workspace must pass.
How we build
- Script state retrieval through a Spacelift task or external state access, keeping credentials out of logs and repositories.
- Push exported state to your own bucket with versioning and access controls defined before the first transfer.
- Run OpenTofu or Terraform plans against each migrated state and record any drift before anything is applied.
How we hand over
- Deliver a runbook listing each workspace, its source state, target location and the plan result from the check.
- Document rollback steps for each stack so the original state can be restored if a plan shows unexpected changes.
- Walk your platform and security teams through the evidence so they can confirm the export against their own records.
How we support
- Engagements are fixed-scope, so the agreed deliverables and timeline are set in writing before work starts.
- Ongoing support, upgrades and continuous testing of the new state backend are available as a retainer.
- Confirm with DeployOpen during scoping which support terms, response expectations and handover dates apply to your environment.

