galah92
galah92

Reputation: 4001

Why does Terraform fail to provision google_cloudfunctions_function_iam_member?

While I am able to provision a single HTTP-triggered GCP cloud function and call it publicly, I can't seem to provision my second function to be called publicly as well.

I have the editor role assigned to my Terraform service account.

google_cloudfunctions_function_iam_member.v2invoker: Creating...
╷
│ Error: Error applying IAM policy for cloudfunctions cloudfunction "projects/myproject/locations/us-central1/functions/v2": Error setting IAM policy for cloudfunctions cloudfunction "projects/myproject/locations/us-central1/functions/v2": googleapi: Error 403: Permission 'cloudfunctions.functions.setIamPolicy' denied on resource 'projects/myproject/locations/us-central1/functions/v2' (or resource may not exist).
│ 
│   with google_cloudfunctions_function_iam_member.v2invoker,
│   on main.tf line 460, in resource "google_cloudfunctions_function_iam_member" "v2invoker":
│  460: resource "google_cloudfunctions_function_iam_member" "v2invoker" {

Clarification - the function resource itself is provisioned correctly, only the iam_member resource isn't.

My Terraform config:

resource "google_cloudfunctions_function" "v2" {
  name                  = "v2"
  runtime               = "nodejs12"
  available_memory_mb   = 128
  source_archive_bucket = google_storage_bucket.functions.name
  source_archive_object = google_storage_bucket_object.nodejs_functions.name
  entry_point           = "v2"

  trigger_http = true
}

resource "google_cloudfunctions_function_iam_member" "v2invoker" {
  project        = google_cloudfunctions_function.v2.project
  region         = google_cloudfunctions_function.v2.region
  cloud_function = google_cloudfunctions_function.v2.name

  role   = "roles/cloudfunctions.invoker"
  member = "allUsers"
}

output "function-v2" {
  value = google_cloudfunctions_function.v2.https_trigger_url
}

Added the terraform config for the first (successful) function:

resource "google_cloudfunctions_function" "helloWorld" {
  name                  = "helloWorld"
  runtime               = "nodejs12"
  available_memory_mb   = 128
  source_archive_bucket = google_storage_bucket.functions.name
  source_archive_object = google_storage_bucket_object.nodejs_functions.name
  entry_point           = "helloWorld"

  trigger_http = true
}

# IAM entry so all users can invoke the function
resource "google_cloudfunctions_function_iam_member" "invoker" {
  project        = google_cloudfunctions_function.helloWorld.project
  region         = google_cloudfunctions_function.helloWorld.region
  cloud_function = google_cloudfunctions_function.helloWorld.name

  role   = "roles/cloudfunctions.invoker"
  member = "allUsers"
}

output "function-helloWorld" {
  value = google_cloudfunctions_function.helloWorld.https_trigger_url
}

The current service account used by terraform is one I created with "Editor" role.

Upvotes: 1

Views: 1663

Answers (1)

Ermiya Eskandary
Ermiya Eskandary

Reputation: 23702

According to GCP IAM documentation:

Note: The Editor role contains permissions to create and delete resources for most Google Cloud services. However, it does not contain permissions to perform all actions for all services. See the section above for more information on how to check if a role has the permissions that you need.

Your editor role definitely doesn't have access to perform the cloudfunctions.functions.setIamPolicy action on the cloud function (as the error message mentions).

Assign the Cloud Functions Admin role (roles/cloudfunctions.admin) to the service account.

It should definitely have all permissions required for anything cloud function-related, including but not limited to setting IAM policies on functions.

Upvotes: 2

Related Questions