kumar
kumar

Reputation: 9387

In Terraform is it possible to move to state from one workspace to another

When starting of I was using the default workspace. Due to increased complexity I would like to use multiple workspaces. I want to move what is in default workspace into its own workspace or rename the default workspace as another workspace. How can I do this?

Upvotes: 27

Views: 30145

Answers (4)

Dantheman91
Dantheman91

Reputation: 884

Here's a step by step way to do this that's a little different than the default answer.

First, we have a default s3 backend.

terraform {
  backend "s3" {
    encrypt        = true
    bucket         = "cool-bucket-name"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "cool-dynamo-db-lock-name"
  }
}

Now, check our workspaces.

terraform workspace list

  default  
* weird-workspace-name

Pull the state down by first commenting out the terraform backend.

#terraform {
#  backend "s3" {
#    encrypt        = true
#    bucket         = "cool-bucket-name"
#    key            = "production/terraform.tfstate"
#    region         = "us-east-1"
#    dynamodb_table = "cool-dynamo-db-lock-name"
#  }
#}

Run the command to migrate the state locally.

terraform init -migrate-state

You can check the state and see if it's still good to go.

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Next, pull the state. The name of the state file is determined by what you originally gave as the key.

terraform workspace new cool-workspace-name

terraform state push terraform.tfstate

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Alright, now go clean up your old state.

terraform workspace select weird-workspace-name

terraform state list | cut -f 1 -d '[' | xargs -L 0 terraform state rm

terraform workspace select cool-workspace-name

terraform workspace delete weird-workspace-name

Run the terraform apply command again.

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

And now move your state back into S3, uncomment the terraform backend.tf file.

terraform {
  backend "s3" {
    encrypt        = true
    bucket         = "cool-bucket-name"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "cool-dynamo-db-lock-name"
  }
}

Run:

terraform init -migrate-state

I really appreciate the answer by bhalothia, I just wanted to add another step by step that's a little bit of a different case.

Upvotes: 3

bhalothia
bhalothia

Reputation: 1510

Yes it is possible to migrate state between workspaces.

I'm assuming that you are using S3 remote backend and terraform version >= 0.13 Let's see how this state surgery looks like:

Sample resource config that needs to be migrated between workspaces:

provider "local" {
  version = "2.1.0"
}

resource "local_file" "foo" {
  content  = "foo!"
  filename = "foo.bar"
}

terraform {
  backend "s3" {
    bucket         = ""
    region         = ""
    kms_key_id     = ""
    encrypt        = ""
    key            = ""
    dynamodb_table = ""
  }
}

Let's initialise the backend for the default workspace and apply:

terraform init
<Initialize the backend>

terraform workspace list
* default

terraform apply
local_file.foo: Refreshing state... [id=<>]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed

So, as you can see a local file was already created and the state is stored in the default workspace. Terraform apply didn't change anything.

Now, we want to migrate to a new workspace:

Pull the state while you are still in the default workspace

terraform state pull > default.tfstate

Create a new workspace; let's call it test

terraform workspace new test
Created and switched to workspace "test"!

If you try to run terraform state list, you should not see any state. Let's push the state to newly created workspace and see what's in the state; also what happens when we apply.

terraform state push default.tfstate

terraform state list
local_file.foo

terraform apply
local_file.foo: Refreshing state... [id=<>]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Your local_file.foo has been migrated to the test workspace.

Don't forget to switch back to the default workspace and remove state references for this file.

terraform workspace select default
terraform state rm local_file.foo
Removed local_file.foo
Successfully removed 1 resource instance(s).

PS: I would highly recommend reading more about managing Terraform state.

Upvotes: 62

JB68
JB68

Reputation: 192

None of previews answers worked for me, every time the new workspace is empty as it should be. In order to populate it you need to use -state as per documentation. https://www.terraform.io/cli/commands/workspace/new

So what worked:

  • Create a local backup terraform state pull > default.tfstate
  • Switch to local by commenting the backend block then terraform init -migrate-state
  • Create your new workspace with terraform workspace new -state=default.tfstate newspace This will copy the default into newspace
  • Do a terraform plan to check
  • Uncomment backend block to switch back in the cloud then run terraform init -migrate-state to migrate your new workspace in the cloud
  • Do a terraform plan and terraform workspace list to check.

Upvotes: 7

Simao Gomes Viana
Simao Gomes Viana

Reputation: 631

Depending on the backend, Terraform might be able to do the migration on its own.

For this, just update your backend configuration in the terraform block and then run following command to migrate the state automatically:

terraform init -migrate-state

Doing so will copy the state of all workspaces defined from old to new.

I can confirm this to be working on Terraform Cloud, even with multiple workspaces defined using a prefix.

Upvotes: 1

Related Questions