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.