Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Terraform + GCP Authentication

Prerequisites

# Terraform is already installed — verify
terraform version

# ADC is a separate login from gcloud CLI login
gcloud auth application-default login   # opens browser

# Verify ADC is working
gcloud auth application-default print-access-token

gcloud auth logingcloud auth application-default login. The first is for the CLI only. Terraform uses ADC — you need both.


ADC scope

ADC is scoped to a Google Account (user identity), not to a project or org.

~/.config/gcloud/application_default_credentials.json
└── authenticates as: you@gmail.com
    └── can reach: any project/folder/org your account has IAM on

One login → access to all projects where your account has permissions. The project in the Terraform provider block is just "where to create resources" — it does not affect credentials.

gcloud auth application-default login
                │
                ▼
    your Google Account identity
                │
    ┌───────────┼───────────┐
    ▼           ▼           ▼
 project-A   project-B   project-C   ← all accessible via IAM

When you need multiple credential files

SituationSolution
Same user, multiple projectsOne ADC file — change project in provider
Same user, multiple orgsOne ADC file — IAM bindings per org
Act as a SA (no key)One ADC file + impersonate_service_account in provider
Act as a SA (with key)GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
Different Google usersRe-run application-default login (overwrites the file)

ADC credential expiry

ADC user credentials use OAuth2 refresh tokens:

TokenLifetime
Access token~1 hour — auto-refreshed transparently
Refresh tokenLong-lived (years) — invalidated only on revocation

You never need to re-login under normal use. The refresh token is invalidated if you revoke access, change your Google password, or an admin forces session expiry.


Option A — Multiple projects, one login

Same user account, different project per provider alias. Works out of the box with one ADC login.

terraform {
  required_providers {
    google = { source = "hashicorp/google", version = "~> 6.0" }
  }
}

provider "google" {
  alias   = "dev"
  project = "praxedo-dev"
  region  = "europe-west1"
}

provider "google" {
  alias   = "prod"
  project = "praxedo-prod"
  region  = "europe-west1"
}

Reference the right provider per resource:

resource "google_storage_bucket" "raw" {
  provider = google.dev
  name     = "raw-lake-dev"
  location = "EU"
}

Option B — SA key file (avoid where possible)

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa-key.json
terraform apply

Key files on disk are a security risk. Prefer impersonation (Option C) instead.


No key file. Your ADC user token calls the Token Creator API → gets a short-lived SA token → Terraform uses that SA token for all API calls.

your user (ADC) → impersonates → terraform-sa → acts on → project resources

Setup

Step 1 — Create the SA and grant it roles on the target project:

gcloud iam service-accounts create terraform-sa \
  --project=MY_PROJECT \
  --display-name="Terraform deployer"

gcloud projects add-iam-policy-binding MY_PROJECT \
  --member="serviceAccount:terraform-sa@MY_PROJECT.iam.gserviceaccount.com" \
  --role="roles/editor"

Step 2 — Grant your user the right to impersonate it (binding ON the SA as a resource):

gcloud iam service-accounts add-iam-policy-binding \
  terraform-sa@MY_PROJECT.iam.gserviceaccount.com \
  --member="user:you@gmail.com" \
  --role="roles/iam.serviceAccountTokenCreator"

Step 3 — Terraform provider config:

provider "google" {
  impersonate_service_account = "terraform-sa@MY_PROJECT.iam.gserviceaccount.com"
  project                     = "MY_PROJECT"
  region                      = "europe-west1"
}

Why this is the right pattern for multi-env setups

Direct ADC userSA impersonation
Key file on diskNoNo
Blast radius if session leakedYour full accountOnly this SA's permissions
Audit trailYour personal userterraform-sa — clean separation
Per-environment scopingNot possibleYes — one SA per env
Revoke accessRevoke your whole sessionRemove the TokenCreator binding

For a multi-environment Praxedo setup:

terraform-sa-dev@praxedo-dev.iam.gserviceaccount.com   → roles scoped to dev
terraform-sa-prod@praxedo-prod.iam.gserviceaccount.com → roles scoped to prod

quota_project_id in ADC

When ADC is configured, GCP sets a quota_project_id in the credentials file. This is the project used for API quota tracking and billing — it is not the project where resources are deployed.

# Change it without re-authenticating
gcloud auth application-default set-quota-project MY_PROJECT

It must point to a billing-enabled project. For local dev your personal project is fine.