Skip to content

Authenticating with GCP

Terragrunt reads GCP credentials from the sources below to bootstrap, migrate, and delete the gcs state backend. The gcs backend in OpenTofu/Terraform and the Google provider read the same sources.

Pick whichever credential source fits where Terragrunt is running:

On a workstation, log in with Application Default Credentials. Terragrunt and the providers pick them up from the default credential chain:

Terminal window
gcloud auth application-default login
terragrunt apply

gcloud auth login on its own is not enough. It signs in the gcloud CLI, but it does not write the Application Default Credentials that Terragrunt and the providers read.

To act as a different service account than the one you signed in as, set impersonate_service_account in the remote_state config. Terragrunt and the gcs backend both use it. The identity you signed in as needs the Service Account Token Creator role (roles/iam.serviceAccountTokenCreator) on that service account. For a delegation chain, also set impersonate_service_account_delegates. The Google provider takes its own impersonate_service_account argument, as in the provider generate example.

Set impersonation and credentials in the remote_state config or the variables above. Terragrunt does not read GOOGLE_BACKEND_CREDENTIALS, GOOGLE_BACKEND_IMPERSONATE_SERVICE_ACCOUNT, or GOOGLE_IMPERSONATE_SERVICE_ACCOUNT. The gcs backend in OpenTofu/Terraform does. With only those set, Terragrunt creates and checks the bucket as one identity, and OpenTofu/Terraform reads state as another.

Keep access tokens in GOOGLE_OAUTH_ACCESS_TOKEN rather than in the access_token config. OpenTofu/Terraform copies backend configuration into .terraform/terraform.tfstate and into saved plan files, so a token placed in remote_state.config ends up on disk in plain text.

The auth provider command works for GCP too. Return GOOGLE_OAUTH_ACCESS_TOKEN or GOOGLE_APPLICATION_CREDENTIALS in its envs map to select credentials per unit at runtime.

Reading, writing, and locking state needs object access on the bucket, e.g. the Storage Object User role (roles/storage.objectUser).

backend bootstrap, backend migrate, and backend delete also read the bucket’s metadata, which needs storage.buckets.get. Object roles do not include it. Without it, Terragrunt cannot tell the bucket exists, so bootstrap offers to create it and migrate and delete refuse to run without --force. The Storage Legacy Bucket Reader role (roles/storage.legacyBucketReader) on the bucket grants it.

Creating the bucket needs storage.buckets.create on the project, and applying gcs_bucket_labels needs storage.buckets.update. The Storage Admin role (roles/storage.admin) on the project covers both. If the identity must not create buckets, create the bucket in advance and set skip_bucket_creation in the remote_state config.