DEV Community

Igor Souza
Igor Souza

Posted on • Edited on

Moving resources from the default workspace to a new one on Terraform.

Step 1 - First things first

I'll assume that you are using remote states for two main reasons:
You should be doing this.
It's harder to move the resources, so when I explain how to do this on remote states you will be able to do this on local states.

First thing you need to do is remove your backend. You probably have something like this:

terraform {
  backend "s3" {
    bucket = "bucket-name"
    key    = "terraform.tfstate"
    region = "us-east-1"
  }
}
Enter fullscreen mode Exit fullscreen mode

You don't need to delete it, just comment all these lines.

Why? 
Because we need to pull our tfstate to our local machine.

To pull the tfstate from remote to local storage we just need to run terraform init.

It will download all the modules and give you the following output:

Do you want to migrate all workspaces to "local"?
 Both the existing "s3" backend and the newly configured "local" backend support workspaces. When migrating between backends, Terraform will copy all workspaces (with the same names). THIS WILL OVERWRITE any conflicting states in the destination.
 
 Terraform initialization doesn't currently migrate only select workspaces.
 If you want to migrate a select number of workspaces, you must manually
 pull and push those states.
 
 If you answer "yes", Terraform will migrate all states. If you answer
 "no", Terraform will abort.
Enter a value:
Enter fullscreen mode Exit fullscreen mode

As we don't have any other workspace yet, let's put yes and wait.
Couple seconds should be enough to get the message:

Terraform has been successfully initialized!
Now, you can do a ls terraform.state and you see the file created.

Step 2 - Setting up the workspace

Now that we already have the state file on our local storage, we can move the resources.
If you are not using remote storage, you should be using, your work starts here!

We need to create our workspace so let's run the following command:

terraform workspace new name_of_workspace
Enter fullscreen mode Exit fullscreen mode

In my case I've done:

terraform workspace new qa
Enter fullscreen mode Exit fullscreen mode

To validate that we don't have any resources lets do this:

terraform workspace list
  default
* qa
Enter fullscreen mode Exit fullscreen mode

To check if we are in the correct workspace, then run:

terraform state list
Enter fullscreen mode Exit fullscreen mode

You should get something like:

No state file was found!
State management commands require a state file. Run this command
in a directory where Terraform has been run or use the -state flag
to point the command to a specific state location.
Enter fullscreen mode Exit fullscreen mode

Step 3 - Let's do magic!

You will need to pay a lot of attention here. We will use the terraform state push command.
Run:

terraform state push terraform.tfstate
Enter fullscreen mode Exit fullscreen mode

If you get some error we always had the -force tag ;)

terraform state push -force terraform.tfstate
Enter fullscreen mode Exit fullscreen mode

Now, let's run the terraform state list again :

terraform state list

module.qa_environment.aws_availability_zones.available
...
Enter fullscreen mode Exit fullscreen mode

Step 4 - Cleaning up

We can't leave the default workspace with the same resources, we can have problems with two workspaces managing the same resources, so let's clean it!
First, we need to move to default workspace:

terraform workspace select default
Enter fullscreen mode Exit fullscreen mode

Now, let's list all the resources available:

terraform state list
module.qa_environment.aws_availability_zones.available
Enter fullscreen mode Exit fullscreen mode

In my case, as I only have the module qa_environment , I'll run this:

terraform state rm module.qa_environment
Enter fullscreen mode Exit fullscreen mode

This will remove all nested resources.

Step 5 - Moving data to remote storage.

Let's just uncomment these lines:

terraform {
  backend "s3" {
    bucket = "bucket-name"
    key    = "terraform.tfstate"
    region = "us-east-1"
  }
}
Enter fullscreen mode Exit fullscreen mode

and run

terraform init
Enter fullscreen mode Exit fullscreen mode

You will be asked if want to move all data to a new remove state. Just press yes and you are good to go! :)

Quick Tip

If you are using some CI/CD tool, don't forget to add the following command as a pipeline step:

terraform workspace select environment_name
Enter fullscreen mode Exit fullscreen mode

Without this, you will try to recreate all resources on default workspace and probably will get some error.

Top comments (3)

Collapse
 
chiefy profile image
Christopher "Chief" Najewicz

This saved me so many headaches, thank you! Honestly the docs around workspace migration could really use something like this to help migrate existing default workspace state to a newly named WS - it is not straightforward if you're using remote state! Thanks again!

Collapse
 
mrostanski profile image
MRostanski

This is the best article on the subject I found. Straight to the point and totally working without a fuss! Have a great day, friend.

Collapse
 
igordcsouzaaa profile image
Igor Souza

Glad that you like it! :)
Thanks for the feedback!