I have made a terrible choice naming my workspace, and would like to move all resources in it to a workspace with a better name. Is there a short way of doing this? My backend is S3, there is no state locking.
I have considered, but not actually done, the following:
- backup the state (
terraform state pull) – then what? import using legacy method?
- import resources the hard way ← I really don’t want to do that.
What are you state ninjas doing when you need to move resources to another workspace?
Since you are using S3 without any locking, honestly the easiest method is likely to be to use the S3 CLI or admin console directly to rename the object representing the workspace you want to rename. The S3 backend scans the set of objects in the bucket and does prefix-matching to see which workspaces are available, so as long as you preserve the existing naming convention and ensure that nobody else tries to work with the workspace while you are in the process of renaming it this approach should be sufficient.
Within Terraform’s own abstractions, you were on the right track with
terraform state pull, which retrieves the latest state snapshot from the current workspace. The opposite of that command is
terraform state push, which allows you to push an on-disk state snapshot into the current workspace.
So a Terraform-commands-only version of what you want to achieve could look like this:
terraform workspace select old-name
terraform state pull >old-name.tfstate
terraform workspace new new-name
terraform state push old-name.tfstate
terraform show just to confirm that the newly-imported state looks “right”, before we delete the old workspace
terraform workspace delete -force old-name
The state manipulation commands run through Terraform’s automatic state upgrading processes and so best to do this with the same Terraform CLI version that you’ve most recently been using against this workspace so that the state won’t be implicitly upgraded as part of the operation. (Upgrading generally shouldn’t hurt, but since the intended effect was a “rename” here I assume it’s preferable for the new state to be equivalent to the old state.)
Whichever way you do it, I strongly recommend making sure that the old workspace is deleted properly before you conclude your work because otherwise you will have created a situation that violates a couple of of Terraform’s core assumptions: that each object is only managed in only one Terraform workspace, and that the state snapshots for each workspace have a separate “lineage” (an automatically-generated unique id) so that Terraform can detect situations like trying to apply a plan in a different workspace than where it was created, etc.
Thanks, it worked. The only problem I had is deleting the old workspace. My infrastructure was deployed in default workspace and I wasn’t able to delete it after creating a new one.
What if you are using state locking (dynamoDB), can I still follow the workspace select-pull-push method?
This is a very old topic so if you have further questions it’d probably be best to start a new one, but the main concern if you are using locking is to make sure there aren’t any locks held when you do a rename in S3, so that you don’t get stale lock records left behind in the DynamoDB table. That’d probably include coordinating with the rest of your team to make sure nobody else tries to do anything with Terraform while you are doing this work, or if out-of-band communication isn’t possible then to temporarily use a bucket policy to lock out access to anyone except you.