Introduction
This article outlines command-line interface (CLI) based methods to migrate Terraform state across different organizations, backends, or between Terraform Enterprise (TFE) instances. These workflows support several common scenarios:
-
Reverting or modifying state within an HCP Terraform or Terraform Enterprise workspace using
terraform state pullandpush. - Migrating a workspace to a different organization in HCP Terraform or Terraform Enterprise.
- Transferring state between separate Terraform Enterprise instances using the TFE API.
Each procedure below provides detailed steps for these scenarios, applicable across Terraform CLI, HCP Terraform, and Terraform Enterprise environments.
Procedures
Method 1: Reverting or Modifying Workspace State
The current versions of Terraform Enterprise (TFE) and HCP Terraform do not provide a feature to revert state within the application. You can use the Terraform CLI to push a state file into a workspace to make it the current state.
-
To obtain the desired state, navigate to the workspace’s States list, select the desired state, and click Download or Download raw to download the state file to your local machine.
-
Configure Terraform locally with the HCP Terraform cloud integration and run
terraform init. -
With the
cloudblock configured and Terraform initialized, you can use thestate mvandstate rmcommands to directly modify the state within the TFE or HCP Terraform workspace. -
In scenarios where the state was updated incorrectly or corrupted, you may need to pull the state file to your local directory for editing. Use the following command to pull the state.
$ terraform state pull -
After editing the state file locally, upload it using the following command, where
/path/to/statefile.jsonis the path to your updated state file.$ terraform state push /path/to/statefile.json
Method 2: Migrating a Workspace Between Organizations
To migrate a workspace to a different organization, you will need a user API token with sufficient permissions in both the source and destination organizations. You can generate a token at https://app.terraform.io/app/<your-organization>/settings/authentication-tokens for HCP Terraform or https://<tfe-url>/app/<your-organization>/settings/authentication-tokens for TFE.
Ensure that all settings (VCS, variables, SSH keys, Terraform version, etc.) are identical in both the source and destination workspaces.
-
Download the same version of the Terraform CLI that is used in the workspaces.
-
Locally, create a file named
remote.tfthat points to the source organization. Do not commit this file to your VCS repository.terraform { cloud { hostname = "<TFE_HOSTNAME_OR_app.terraform.io>" organization = "<source_organization_name>" workspaces { name = "<source_workspace_name>" } } } -
From a command prompt in the directory containing
remote.tf, log in to the Terraform API.$ terraform login -
Follow the prompts. You will be asked for the user API token.
-
Initialize Terraform to establish communication.
$ terraform init -
Ensure the destination organization and workspace exist. If not, create them before proceeding.
-
Modify the
remote.tffile to point to the destination organization.terraform { cloud { hostname = "<TFE_HOSTNAME_OR_app.terraform.io>" organization = "<destination_organization_name>" workspaces { name = "<destination_workspace_name>" } } } -
Execute
terraform initwith the-migrate-stateflag to begin the migration. Terraform should prompt you to copy the state file to the new workspace. Enteryesto confirm.$ terraform init -migrate-state -
Verify that the new state file appears in the destination workspace.
-
If you are not prompted to move the state file, you can rename the local state file to
statefile.jsonand push it manually.$ terraform state push /path/to/statefile.json
Method 3: Migrating State Between Terraform Enterprise Instances
This procedure explains how to migrate a Terraform state file from one TFE instance to another using the TFE API.
Prerequisites
Before you begin, ensure you have the following information:
-
${HOSTNAME_OLD}: The hostname for the source TFE instance. -
${HOSTNAME_NEW}: The hostname for the target TFE instance. -
${TOKEN_OLD}: The user API token for the source TFE instance. -
${TOKEN_NEW}: The user API token for the target TFE instance. -
${WORKSPACE_ID_OLD}: The workspace ID for the source workspace. -
${WORKSPACE_ID_NEW}: The workspace ID for the target workspace.
Procedure
-
Gather Information from the Source Instance
- Obtain the hostname (
${HOSTNAME_OLD}) and create a user API token (${TOKEN_OLD}). - Retrieve the source workspace ID (
${WORKSPACE_ID_OLD}). You can find this in the workspace Settings > General tab in the TFE UI.
- Obtain the hostname (
-
Download the Source State File
-
Use the following
curlcommand to retrieve the download URL for the current state file.$ curl \ --header "Authorization: Bearer ${TOKEN_OLD}" \ --header "Content-Type: application/vnd.api+json" \ https://${HOSTNAME_OLD}/api/v2/workspaces/${WORKSPACE_ID_OLD}/current-state-version -
Download the state file from the
hosted-state-download-urlprovided in the response. Save the file as${WORKSPACE_ID_OLD}.tfstate.
-
-
Gather Information from the Target Instance
- Obtain the hostname (
${HOSTNAME_NEW}) and create a user API token (${TOKEN_NEW}). - Create a new workspace in the target TFE instance, ensuring it uses the same VCS provider, variables, and Terraform version as the source workspace.
- Lock the new workspace by navigating to Settings > Locking and clicking Lock.
- Retrieve the new workspace ID (
${WORKSPACE_ID_NEW}).
- Obtain the hostname (
-
Prepare the Source State File for Migration
-
Open the downloaded
${WORKSPACE_ID_OLD}.tfstatefile and note theserialandlineagevalues. -
Compute the MD5 checksum of the state file.
$ md5sum ${WORKSPACE_ID_OLD}.tfstate -
Compute the base64-encoded content of the state file.
$ base64 -i ${WORKSPACE_ID_OLD}.tfstate | tr -d '\n' -
Create a file named
${WORKSPACE_ID_OLD}-payload.jsonwith the following content, replacing the placeholder values. Theserialattribute must be a number (not enclosed in quotes).{ "data": { "type": "state-versions", "attributes": { "serial": <SERIAL>, "md5": "<MD5_CHECKSUM>", "lineage": "<LINEAGE>", "state": "<BASE64_CONTENT>" } } }
-
-
Upload the State File to the Target Workspace
-
Use the following
curlcommand to upload the state file to the new TFE workspace.$ curl \ --header "Authorization: Bearer ${TOKEN_NEW}" \ --header "Content-Type: application/vnd.api+json" \ --request POST \ --data @${WORKSPACE_ID_OLD}-payload.json \ https://${HOSTNAME_NEW}/api/v2/workspaces/${WORKSPACE_ID_NEW}/state-versions
-
-
Verify the Migration
- Check the target TFE workspace to confirm that the new state file is listed.
-
Unlock the Target Workspace
- Unlock the new workspace by navigating to Settings > Locking and clicking Unlock.
-
Repeat for Additional Workspaces
- Repeat this process for each workspace state you wish to migrate.
Additional Information
- The Terraform state commands (
mv,rm,push) and theimportcommand will update the Terraform CLI version recorded in the state file. Ensure you are using the same Terraform CLI version as the one configured in the target workspace to avoid version conflicts. - The
terraform state pushcommand is different from the deprecatedterraform pushcommand. - For more examples, refer to the Import Terraform configuration and Manage Resources in Terraform State tutorials.
- For more details on the API, see the Terraform Enterprise API Documentation for Workspaces.