When deploying Cloud Run services with Terraform, a PermissionDenied error occurs because the Terraform service account or Cloud Run Service Agent lacks required IAM roles. This prevents Terraform from creating or updating Cloud Run services.
This error indicates that the authenticated identity (your Terraform service account) does not have sufficient permissions to create or manage Cloud Run services in your GCP project. The error typically stems from missing IAM roles on either the Terraform execution account or the Cloud Run Service Agent. GCP uses Identity and Access Management (IAM) to control access to resources, and attempting operations without the required roles triggers this permission denied response.
Check your Terraform provider block to ensure it references the correct credentials file and project ID:
provider "google" {
credentials = file("path/to/service-account-key.json")
project = "your-gcp-project-id"
region = "us-central1"
}Confirm the service account key file exists and is valid.
Use the gcloud CLI to grant the Terraform service account the Cloud Run Admin role:
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:terraform-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.admin"Replace terraform-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com with your actual Terraform service account email.
The Terraform service account must be able to use the Cloud Run service account. Grant this permission:
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:terraform-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"This allows Terraform to deploy services that use service accounts.
Grant the Cloud Run Service Agent the required roles/run.serviceAgent role:
PROJECT_NUMBER=$(gcloud projects describe YOUR_PROJECT_ID --format='value(projectNumber)')
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:service-${PROJECT_NUMBER}@serverless-robot-prod.iam.gserviceaccount.com" \
--role="roles/run.serviceAgent"This gives the Cloud Run system the permissions it needs to manage services.
Ensure the necessary APIs are enabled on your GCP project:
gcloud services enable run.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
YOUR_PROJECT_IDThe Cloud Run API, Cloud Resource Manager API, and IAM API must be active for Terraform operations.
After granting roles, wait 10-30 seconds for IAM changes to propagate across GCP systems, then retry:
terraform applyIf the error persists, roles may still be propagating. Wait a minute and try again. If it continues to fail, verify all roles were granted to the correct service accounts using:
gcloud projects get-iam-policy YOUR_PROJECT_ID --flatten="bindings[].members"For service accounts created recently, IAM permission propagation can cause transient 403 errors. These typically resolve after waiting 30-60 seconds and retrying. If you are deploying a Cloud Run service that accesses other GCP resources (Cloud SQL, Secrets Manager, Cloud Storage), ensure the Cloud Run service account (not the Terraform account) has the appropriate roles on those resources. Use the google_cloud_run_service_iam_binding resource in Terraform to manage who can invoke your service. When using service account impersonation in Terraform, ensure the impersonating account has the roles/iam.serviceAccountTokenCreator role.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform