Tutorials
Tutorials
June 8, 2023

How to move Terraform State into a remote backend

By
Edgar Mocharnyk
Breaking down monolithic Terraform workspaces into smaller ones is a common best practice. Workspaces with a smaller amount of resources will execute faster and are easier to troubleshoot. Using the terraform state mv command is straightforward when you’re executing locally, but how do you do this in a remote backend? We’ll go through this step by step.

Step 1:

If your workspace is VCS based, you’ll want to make sure you add the remote backend to your code to be able to use the Terraform CLI to pull down and manipulate the state. First, use terraform login to get an API credential if you haven’t done so already. In this case, we are using Scalr as the backend:
terraform login <account-name>.scalr.io

Step 2:

Add the remote or cloud backend type to your Terraform code to allow for the local workspace to interact with the backend. Make sure to update your values and add the workspace that you want to move resources from:

terraform {
  backend "remote" {
    hostname = "<my-account>.scalr.io"
    organization = "<ID of environment>"
    workspaces {
      name = "<workspace-name>"
    }
  }
}

Step 3:

Now, pull the state:

terraform state pull> terraform.tfstate

Step 4:

Switch the backend from the remote/cloud mode to local by commenting out the remote backend configuration from the source code:

#terraform {
  #backend "remote" {
    #hostname = "<my-account>.scalr.io"
    #organization = "<ID of environment>"
    #workspaces {
      #name = "<workspace-name>"
    #}
  #}
#}

Step 5:

Now run a reconfigure to make sure the backend updates:

terraform init -reconfigure

Step 5a:

Depending on the Terraform version, you may have to add the backend as local for reconfigure to work. If it already worked, ignore this step:

terraform {
  backend "local" {
   }
}

Step 6:

terraform state mv  -state-out=terraform-second.tfstate <source.address> <destination.address>

If the above fails with the error “Backend initialization required, please run "terraform init": Reason: Unsetting the previously set backend "remote"”, please see the Step 5a.

If it works, you’ll see the following output:

Move "random_integer.second" to "random_integer.primary"

Successfully moved 1 object(s).

Step 7:

After the resources have been split, you can start refactoring the source Terraform code into different folders. In my case, I now have 2 directories for each workspace.

Now , you must re-enable the backend in each workspace by removing the previous commented out lines:

terraform {
  backend "remote" {
    hostname = "<my-account>.scalr.io"
    organization = "<ID of environment>"
    workspaces {
      name = "<workspace-name>"
    }
  }
}

Step 8:

Run terraform init terraform init on the new workspace. You will be asked if you want to copy the existing state, which you should answer “yes” to. After the init finishes you will now see the state in the next workspace.

Step 9:

Lastly, you’ll want to push the updated state back into the existing workspace. Make sure the remote backend is enabled again and run terraform init -reconfigure. You will be asked if you want to copy the existing state, which you should answer “yes” to. You’ll now see the updated state in the existing workspace. Make sure to use or free plan to try this out and get started today.
Note: While this blog references Terraform, everything mentioned in here also applies to OpenTofu. New to OpenTofu? It is a fork of Terraform 1.5.7 as a result of the license change from MPL to BUSL by HashiCorp. OpenTofu is an open-source alternative to Terraform that is governed by the Linux Foundation. All features available in Terraform 1.5.7 or earlier are also available in OpenTofu. Find out the history of OpenTofu here.

Start using the Terraform platform of the future.

A screenshot of the modules page in the Scalr Platform