title: Provider configuration description: Sensible defaults for the google and google-beta providers: pinning, project/region/zone, user_project_override, ADC vs Workload Identity Federation, aliases, and impersonation. tags: - terraform - gcp
Provider configuration¶
GCP provider boilerplate that you'll repeat in almost every stack. Targets the google and google-beta providers ≥ 6.0 with Terraform ≥ 1.3 or OpenTofu ≥ 1.6.
Pin in required_providers¶
terraform {
required_version = ">= 1.3"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 6.0, < 7.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 6.0, < 7.0"
}
}
}
Pin both google and google-beta to the same version range
The two providers ship in lockstep. Mixing versions across them produces confusing schema drift.
Default google and google-beta providers¶
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}
provider "google-beta" {
project = var.project_id
region = var.region
zone = var.zone
}
Setting project, region, and zone here means resource blocks don't have
to repeat them. Resources can still override per-resource.
user_project_override and billing_project¶
Some APIs (notably anything fronted by Service Usage, BigQuery, or "requester-pays" buckets) bill the caller's project, not the resource's project. Set both fields when your auth identity lives in a different project from the resources you're managing:
provider "google" {
project = var.project_id
region = var.region
user_project_override = true
billing_project = var.billing_project_id
}
user_project_override = true tells the provider to send
X-Goog-User-Project: <billing_project> with each request.
Authentication¶
Local development: Application Default Credentials¶
The provider picks up ADC automatically. No credentials = ... argument,
no JSON key on disk.
CI: Workload Identity Federation (no keys)¶
In CI, exchange the runner's OIDC token for a short-lived Google token. With GitHub Actions:
permissions:
id-token: write
contents: read
jobs:
apply:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/github-pool/providers/github
service_account: tf-deployer@acme-platform-prod.iam.gserviceaccount.com
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform apply -auto-approve
The auth action writes credentials to a path in GOOGLE_APPLICATION_CREDENTIALS,
and the google provider transparently picks them up.
Don't ship JSON service-account keys
Static SA keys are the #1 source of GCP credential leaks. Use ADC locally and Workload Identity Federation in CI. See the IAM bindings page for the WIF resource setup.
Provider aliases for multi-project¶
When one stack manages resources across projects (e.g. shared VPC host + service projects), declare an aliased provider per project:
provider "google" {
alias = "host"
project = var.host_project_id
region = var.region
}
provider "google" {
alias = "svc_app"
project = var.app_project_id
region = var.region
}
resource "google_compute_subnetwork" "app" {
provider = google.host
name = "app-subnet"
ip_cidr_range = "10.10.0.0/20"
region = var.region
network = google_compute_network.shared.id
}
resource "google_compute_instance" "api" {
provider = google.svc_app
name = "api"
machine_type = "e2-medium"
zone = var.zone
# ...
}
Modules accept aliased providers via the providers argument:
Impersonate a service account¶
Useful when your human/CI identity has only roles/iam.serviceAccountTokenCreator
on a deploy SA, and the deploy SA holds the actual resource permissions:
provider "google" {
project = var.project_id
region = var.region
impersonate_service_account = "tf-deploy-prod@acme-platform-prod.iam.gserviceaccount.com"
}
Combine with aliases for per-environment impersonation in a single stack:
provider "google" {
alias = "prod"
project = "acme-platform-prod"
region = "us-central1"
impersonate_service_account = "tf-deploy-prod@acme-platform-prod.iam.gserviceaccount.com"
}
provider "google" {
alias = "stg"
project = "acme-platform-stg"
region = "us-central1"
impersonate_service_account = "tf-deploy-stg@acme-platform-stg.iam.gserviceaccount.com"
}
The caller (you, or the CI SA) only needs roles/iam.serviceAccountTokenCreator
on each deploy SA: nothing else.