Learn Terraform with GCP — Part 3

Jayan Menon
4 min readAug 26, 2022

--

We have looked at how to create and update basic resources in GCP using Terraform in Part 1 and Part 2. This article will look into shared state management for Terraform in a GCP environment.

When creating resources, Terraform creates a local state file in your current directory named terraform.tfstate to store the current list of resources and status of deployment. This is a JSON formatted file that contains all the resource parameters and associated metadata of all resources created by Terraform from the code in the current directory.

Each time the terraform apply command is run, the local state file is copied to terraform.tfstate.backup, before the current state file is updated.

Local state files are automatically created and require no additional configuration in the code to be enabled. However, the primary disadvantage of using local state is the inability for multiple users to collaborate on the code. When you are working in a team environment, managing the state file or keeping it in sync among the team members can be extremely inefficient and error prone.

Shared State backends

Shared state management is the solution to managing Terraform state for teams. There are multiple state backends supported by Terraform as listed in the Terraform documentation online.

I choose the term shared state backends since Hashicorp’s definition of Remote state refers to state management through Terraform Cloud, the Freemium version of Terraform, or Terraform Enterprise. There are a few other supported state backends such as Google Cloud Storage (GCS) buckets, AWS S3, Azure storage accounts and various other storage backends that can be used to store the Terraform state in a shared environment.

We will discuss GCS buckets as the shared state backend for our purpose.

Configuration

The basic configuration for a GCS bucket for Terraform state storage is shown below:

terraform {
backend "gcs" {
bucket = "my-tf-backend-bucket"
prefix = "tfstate/my-dev-project-tf"
}
}

The backend configuration is part of the terraform block that we have used in the previous sections. In Part 1, we discussed how the provider version can be specified in the required_providers section in this block. backend is another configuration section within the terraform block.

The configuration parameters vary by provider. For GCS backends, you would specify a storage bucket name via the bucket parameter and a directory path via the prefix. This path will be created on the first initialization of Terraform, and a state file named default.tfstate will be created in the specified path.

With a shared state backend such as this, all team members working on the code will use the same state files to compare and deploy resources. For backends that support file locking, Terraform will automatically lock the state file before any task that would modify the state, and release the lock when completed. The GCS backend supports file locking.

If a Terraform deployment is terminated abnormally, this can cause the lockfile to be left on the state backend and further runs will fail with an error about the active lock file. In these situations, it may be required to manually unlock the state file. The following command allows you to unlock the state file:

terraform force-unlock 

Note: In a shared environment, the fact that a lock exists may not mean that it is due to a crashed run. Some deployments can run into minutes, and another deployment may have a lock on the state file. In such events, forcing unlock on the state file can cause data corruption and may be unrecoverable. Always validate that you are the only user running Terraform before unlocking a state file manually.

Disaster Recovery Considerations

Although not a common occurrence, state files may become corrupted or an unplanned configuration change made it in to the state file. In such cases, you might need to revert to a previous state file.

Terraform does not create backup copies of the state file when resources are deployed in a shared backend like GCS, by default. In this situation, the recommended best practice would be to turn on versioning in your state bucket. The storage subsystem will automatically maintain older versions of (all) files in the bucket. In the event that you need to revert to an older state file, you can then use the GCS storage browser to restore and replace the state file.

Managing State files

Finding specific resource information from state files can be done using the state list and state show commands.

The state list displays a list of the resources by name — if you run this command in our earlier example directory for GCP instance, the output may be similar to this:

$ terraform state list
google_compute_instance.web_server

The state show instead will provide the full information stored for all resources in JSON format.

The command terraform refresh can be used to update the state file to match information on all the deployed resources. This will allow syncing up changes that may have been manually done on the resources outside of Terraform. While this is not a recommended method of keeping state files in sync with resources, it can be handy when there are metadata or tag changes that are done to resources by other processes. This command is also a shortcut to doing a Terraform apply in refresh only mode as shown below.

terraform apply -refresh-only -auto-approve

You can force replacement of a resource despite having no configuration changes. A typical use case might be to rebuild a server that had some internal data or application issues. This can be achieved by using the replace option while running terraform apply .

$ terraform apply -replace="google_compute_instance.web_server"

The terraform state mv and terraform state rm commands allows you to move a resource or delete a resource from a state file. The mv command might be useful to migrate the state for one or more resources to a separate module without having to delete and recreate the resources.

The rm command would allow removing a resource from the state without affecting the actual resource that has been deployed. However, this would stop Terraform from tracking or updating the resource in the future from that code base.

In the next section, we will discuss the use of variables in Terraform.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Jayan Menon
Jayan Menon

Written by Jayan Menon

Cloud Architect at Maven Wave Partners — designing Enterprise solutions for GCP, AWS, Azure. LinkedIn: https://www.linkedin.com/in/jmoolayil/

No responses yet