Store Terraform state in a Cloud Storage bucket Stay organized with collections Save and categorize content based on your preferences.
In this tutorial, you learn how to store Terraform state in a Cloud Storagebucket.
By default, Terraform storesstatelocally in a file namedterraform.tfstate. This default configuration canmake Terraform usage difficult for teams when multiple users run Terraform atthe same time and each machine has its own understanding of the currentinfrastructure.
To help you avoid such issues, this page shows you how to configure aremote state that points to aCloud Storage bucket. Remote state is a feature ofTerraform backends.
Objectives
This tutorial shows you how to do the following:
- Use Terraform to provision a Cloud Storage bucket to storeTerraform state.
- Add templating in the Terraform configuration file to migrate the state fromthe local backend to the Cloud Storage bucket.
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage, use thepricing calculator.
When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, seeClean up.
Cloud Storage incurs costs for storage, read and write operations,network egress, and replication.
The Cloud Storage bucket in this tutorial hasObjectVersioning enabled to keep the history of yourdeployments. Enabling Object Versioning increases storage costs, which you canmitigate by configuringObject Lifecycle Managementto delete old state versions.
Before you begin
In the Google Cloud console, activate Cloud Shell.
Cloud Shell is preinstalled with Terraform.
If you're using a local shell, perform the following steps:
- Install Terraform.
Create local authentication credentials for your user account:
gcloudauthapplication-defaultlogin
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
Create or select a Google Cloud project.
Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
- Create a project: To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission.Learn how to grant roles.
Create a Google Cloud project:
gcloud projects createPROJECT_ID
Replace
PROJECT_IDwith a name for the Google Cloud project you are creating.Select the Google Cloud project that you created:
gcloud config set projectPROJECT_ID
Replace
PROJECT_IDwith your Google Cloud project name.
Verify that billing is enabled for your Google Cloud project.
Enable the Cloud Storage API:
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission.Learn how to grant roles.gcloudservicesenablestorage.googleapis.comGrant roles to your user account. Run the following command once for each of the following IAM roles:
roles/storage.admingcloudprojectsadd-iam-policy-bindingPROJECT_ID--member="user:USER_IDENTIFIER"--role=ROLE
Replace the following:
PROJECT_ID: Your project ID.USER_IDENTIFIER: The identifier for your user account. For examples, see Represent workforce pool users in IAM policies.ROLE: The IAM role that you grant to your user account.
Alternately, you can create acustom IAM role that containsthe following permissions:
storage.buckets.createstorage.buckets.liststorage.objects.getstorage.objects.createstorage.objects.deletestorage.objects.update
As a best practice, we recommend that access to the bucket and the statefiles stored there is controlled. Only a small set of users (for example,the main cloud administrator and the person acting as the alternative orbackup administrator) should have admin permissions for the bucket. Theother developers should have permissions to only write and read objects inthe bucket.
Prepare the environment
Clone the GitHub repository containing Terraform samples:
gitclonehttps://github.com/terraform-google-modules/terraform-docs-samples.git--single-branchChange to the working directory:
cdterraform-docs-samples/storage/remote_terraform_backend_template
Review the Terraform files
Review the
main.tffile:catmain.tfThe output is similar to the following
resource "random_id" "default" { byte_length = 8}resource "google_storage_bucket" "default" { name = "${random_id.default.hex}-terraform-remote-backend" location = "US" force_destroy = false public_access_prevention = "enforced" uniform_bucket_level_access = true versioning { enabled = true }}resource "local_file" "default" { file_permission = "0644" filename = "${path.module}/backend.tf" # You can store the template in a file and use the templatefile function for # more modularity, if you prefer, instead of storing the template inline as # we do here. content = <<-EOT terraform { backend "gcs" { bucket = "${google_storage_bucket.default.name}" } } EOT}This file describes the following resources:
random_id: This is appended to the Cloud Storage bucket name toensure a unique name for the Cloud Storage bucket.google_storage_bucket: The Cloud Storage bucket to storethe state file. This bucket is configured to have the followingproperties:force_destroyis set tofalseto ensure that the bucket is notdeleted if there are objects in it. This ensures that the stateinformation in the bucket isn't accidentally deleted.public_access_preventionis set toenforcedto make sure thebucket contents aren't accidentally exposed to the public.uniform_bucket_level_accessis set totrueto allow controllingaccess to the bucket and its contents usingIAM permissions instead of access control lists.versioningis enabled to ensure that earlier versions of the stateare preserved in the bucket.
local_file: A local file. The contents of this file instructs Terraformto use Cloud Storage bucket as the remote backend once thebucket is created.
Provision the Cloud Storage bucket
Initialize Terraform:
terraforminitWhen you run
terraform initfor the first time, the Cloud Storagebucket that you specified in themain.tffile doesn't exist yet, soTerraform initializes a local backend to store state in the localfile system.Apply the configuration to provision resources described in the
main.tffile:terraformapplyWhen prompted, enter
yes.When you run
terraform applyfor the first time, Terraform provisions theCloud Storage bucket for storing the state. It also creates a localfile; the contents of this file instruct Terraform to use theCloud Storage bucket as the remote backend to store state.
Migrate state to Cloud Storage bucket
Migrate Terraform state to the remote Cloud Storage backend:
terraforminit-migrate-stateTerraform detects that you already have a state file locally and prompts youto migrate the state to the new Cloud Storage bucket. When prompted,enter
yes.
After running this command, your Terraform state is stored in theCloud Storage bucket. Terraform pulls the latest state from this bucketbefore running a command, and pushes the latest state to the bucket afterrunning a command.
Clean up
To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.
Delete the project
To avoid incurring charges to your Google Cloud account for the resourcesused on this page, follow these steps.
Open the
main.tffile.In the
google_storage_bucket.defaultresource, update the value offorce_destroytotrue.Apply the updated configuration:
terraformapplyWhen prompted, enter
yes.Delete the state file:
rmbackend.tfReconfigure the backend to be local:
terraforminit-migrate-stateWhen prompted, enter
yes.Run the following command to delete the Terraform resources:
terraformdestroyWhen prompted, enter
yes.
What's next
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.