Terraform: Migrating Components Between State Files

Illustration of a smiling person playing with a toy train, which has a cat sitting in one of the cars, against a simplistic backdrop with trees. Illustration of a smiling person playing with a toy train, which has a cat sitting in one of the cars, against a simplistic backdrop with trees.

Today we are going to learn how to create and manage state files in Terraform, but we are going to learn too how to migrate objects between different state files. The primary goal of this article is not just about moving data from one state file to another, but also about exploring ways of using state files.

Cloud Native consulting: regardless if you are just getting started, or looking for a big shift from the old ways to the future, we are here to help. About consulting

Terraform state files (or configuration in general) are the place where all the information is stored about the resources that have been created. This means that when we create a component, for example, a service account in a Google Cloud project, Terraform will connect to its state database and add an entry. When we set up our environment we first are going to define where is it our state file located and in our case we are going to choose a GCP bucket.

terraform {
  backend "gcs" {
    bucket = "mkdev-bucket"
    prefix = "terraform/bucket"
  }
}

we tell terraform that there will be a bucket called mkdev-bucket and a folder inside called terraform/bucket where our state file is located.

If we execute terraform init we are going to create and initialize our state file. So now our terraform state is in place but empty. We need a simple code to create an object, for example, a service account.

resource "google_service_account" "service-account" {
  project = “project-is”
  account_id = "test-account"
  display_name = "Service Account for test”
}

now if we execute terraform apply we are going to create an object that will be a service account. If we execute terraform state list we can see that this object has been created, and even if we go to the bucket and we download the state file we can see the code there, similar, but not the same as if we execute terraform state show and the object.

So now how we can migrate this object from one state file to another? The first thing that we need to know is that an object in a state file is only the representation of the service account in this case, and if we remove the object in the state file we are not going to remove the service account in Google Cloud.

To do the migration we had 2 ways, remove and import or move, but since options to do that in terraform move has been deprecated we have only 1 option, so now we only have terraform rm and import.

Something that we are going to need to have is the terraform code in the source and the destination. In our lab, we have 2 folders with the same terraform code and everyone set it up with a different state file in the bucket that we presented before.

If we do for example

terraform state rm object path

now the object has been removed from the initial state folder but the service account is still in GCP. If we go to the second folder and we execute

terraform import object-name projects/my-project/serviceAccounts/my-sa@my-project.iam.gserviceaccount.com

The service account is still in place but the object in terraform will be now in the second state folder. If want to move back to the first terraform state file we need to execute again rm and import

As we have seen the service account never has been removed and always has been located in the same project but we have been able to reference the object in 2 different places.

Cloud Native consulting: regardless if you are just getting started, or looking for a big shift from the old ways to the future, we are here to help. About consulting


Here's the same article in video form for your convenience: