Chapter 2: The Google Provider, Projects & APIs
Topic 11

Authentication and ADC

Auth

The google provider authenticates through Application Default Credentials — ADC — a standard credential-discovery chain that finds your identity without putting any secret in the configuration. You never write a credential into HCL; the provider walks a fixed search order and uses the first credential it finds.

Understanding ADC, and exactly how it differs from your interactive gcloud session, is the line between "it works on my machine" and a CI pipeline that authenticates cleanly. The single most common day-one GCP failure is running the wrong login command and wondering why Terraform cannot see your credentials. This topic fixes that and lays out the ladder of auth methods the next two topics climb.

What ADC Is

ADC is a search order, not a single credential. The provider looks, in order, for: an explicit credentials argument in the provider block, then the GOOGLE_APPLICATION_CREDENTIALS environment variable pointing at a key file, then the user ADC written by gcloud auth application-default login, then the attached service account on a GCE VM, Cloud Build worker, or Cloud Run runner. The first one present wins.

This chain is why the same configuration authenticates correctly on a laptop and in CI without code changes. On the laptop the user ADC is found; in CI the runner's attached service account is found. The provider does not care which — it takes the first credential the search order surfaces.

The ADC search order — first match wins
explicit credentials
GOOGLE_APPLICATION_CREDENTIALS
gcloud ADC
attached service account

Local Development

For local work you write your user ADC with gcloud auth application-default login. This opens a browser, authenticates you, and writes a credential file that SDKs and Terraform read through the ADC chain. It is the standard local-dev posture: no key file, just your own identity on disk in the well-known ADC location.

Writing user ADC for local development
# Writes Application Default Credentials that Terraform reads:
gcloud auth application-default login

# This is NOT the same — it only logs in the gcloud CLI itself:
gcloud auth login

The two commands look almost identical and do completely different things. gcloud auth application-default login writes ADC that Terraform reads; gcloud auth login only authenticates the gcloud CLI for running gcloud commands and writes no ADC at all. Run only the second and Terraform finds no credentials, even though gcloud commands work fine.

Attached Service Accounts

Code running on GCP infrastructure does not need any login at all. A GCE VM, a Cloud Build worker, or a Cloud Run instance has an attached service account, and ADC discovers it automatically through the metadata server — no key file, no interactive login, nothing on disk. The runner simply is that service account.

This is the preferred posture for automation. Run Terraform from a Cloud Build pipeline and it authenticates as the build's service account with zero credential handling on your part. The attached service account sits high on the auth ladder precisely because there is no static secret to leak or rotate.

The Ladder of Auth Methods

The auth methods form a ladder from worst to best. At the bottom are long-lived service-account key files — static JSON secrets that leak and never rotate. Above them, user ADC from application-default login — fine for a human at a laptop, wrong for automation. Above that, an attached service account on a GCP runner — no static secret. Above that, impersonation — short-lived tokens gated by an IAM role. At the top, Workload Identity Federation — keyless external auth.

The two highest rungs are the next two topics. The direction is always the same: climb away from static secrets toward short-lived, identity-gated tokens. A key file should be a last resort you can justify, never the default reach.

Common Failure Modes

Three failures cover most ADC trouble. An empty or wrong ADC — usually because gcloud auth login was run instead of application-default login — produces a "could not find default credentials" error. An expired user login produces an auth error after weeks of working fine; re-run application-default login. And a missing quota project on user ADC produces userProjectMissing on certain APIs.

Diagnose before you go deeper. A trivial data "google_client_config" in a plan resolves the active ADC and tells you which identity Terraform actually sees — far faster than guessing why an apply was denied. Confirm the identity first; debug the IAM grant second.

Verifying which identity ADC resolves
data "google_client_config" "current" {}

output "active_project" {
  value = data.google_client_config.current.project
}

Planning this and reading the output confirms ADC resolved and which project it points at. If the data source itself errors, the problem is the credential chain — not the resource you were trying to create.

gcloud auth login vs application-default login

gcloud auth login — authenticates the gcloud CLI itself so you can run gcloud commands. It writes no Application Default Credentials, so Terraform and other SDKs cannot see it.

gcloud auth application-default login — writes Application Default Credentials that SDKs and Terraform read through the ADC chain. This is the one Terraform needs; confusing the two is the single most common GCP day-one auth failure.

Common Mistakes
  • Running gcloud auth login and expecting Terraform to pick it up — Terraform reads ADC, which that command does not write, so it sees no credentials at all.
  • Committing or baking a service-account key file to authenticate — a long-lived key is the credential most likely to leak and the hardest to rotate.
  • Relying on a personal user ADC in CI — the pipeline breaks when that person's login expires or they leave, and it ties automation to a human identity.
  • Not setting a quota project for user ADC and hitting userProjectMissing on APIs that require one for user credentials.
  • Debugging IAM grants for an hour when the real problem is empty or expired ADC — verify the resolved identity first with google_client_config.
Best Practices
  • Use gcloud auth application-default login for local development and the runner's attached service account in CI/CD.
  • Treat long-lived service-account key files as a last resort; prefer impersonation or Workload Identity Federation, covered next.
  • Keep human identities out of automation — pipelines authenticate as a service account or via federation, never as a person's login.
  • Verify ADC with a trivial data "google_client_config" plan before debugging anything deeper in the credential chain.
  • Set a quota project on user ADC so APIs that require one do not fail with userProjectMissing.
Comparable tools AWS the credential chain — env vars, shared config, instance profile — as the structural analog Azure DefaultAzureCredential walking a similar discovery order gcloud the source of user ADC for local development

Knowledge Check

You ran gcloud auth login and Terraform reports it cannot find credentials. Why?

  • gcloud auth login only authenticates the CLI; Terraform reads ADC, which gcloud auth application-default login writes
  • The login token expired the moment the browser closed and must be re-run as the root user
  • Terraform requires a downloaded service-account key file and ignores every kind of gcloud login
  • The provider block is missing a hard-coded password field for your Google account, and that field must hold your raw account password before any gcloud login subcommand will take effect

What is the ADC search order the provider follows?

  • Explicit credentials, then GOOGLE_APPLICATION_CREDENTIALS, then user ADC, then the runner's attached service account
  • Only the runner's attached service account, ignoring explicit credentials and the environment entirely
  • A random credential picked from whichever file on disk was most recently modified
  • The active Cloud Console browser session cookie, copied out of the logged-in tab, and then nothing else on disk or in the environment at all

Why is a long-lived service-account key file the lowest rung on the auth ladder?

  • It is a static secret that leaks easily and never rotates, unlike short-lived identity-gated tokens above it
  • It is noticeably slower to authenticate each API call than the other credential methods
  • It only works on Windows machines and silently fails on Linux and macOS runners, so the key file is rejected outright on the very CI agents most teams deploy from
  • It cannot be wired into the google provider's credentials field at all

An apply is denied and you suspect a credential problem. What is the fastest first check?

  • Plan a data "google_client_config" to confirm which identity ADC actually resolves
  • Delete the local state file and re-run the entire apply from scratch against the project
  • Downgrade the google provider to an old version released before ADC existed
  • Delete and re-create the whole project to reset its IAM policy

You got correct