Terraform-provider-google: Cloud Functions: Allow / Disable unauthenticated invocations

Created on 5 Mar 2020  路  6Comments  路  Source: hashicorp/terraform-provider-google


Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment. If the issue is assigned to the "modular-magician" user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If the issue is assigned to a user, that user is claiming responsibility for the issue. If the issue is assigned to "hashibot", a community member has claimed the issue already.

Description

Hey there, I am struggling to replicate the functionality of Cloud Functions GUI to stop allowing unauthenticated invocations. In the resources, I have uploaded a imgur picture of the tick box that I am trying to disable.

I have tried the recommendation for creating a google_cloudfunctions_function_iam_binding resource with the cloudfunctions.invoker role on a service account, however, this will still allow any account connect to the cloud function.

New or Affected Resource(s)

  • google_cloudfunctions_cloud_function
  • google_cloudfunctions_function_iam_binding

Potential Terraform Configuration

resource "google_cloudfunctions_function" "function-api" {
   unauthenticated_invocations = true / false
}

References

https://imgur.com/a/eukK8oy
https://www.terraform.io/docs/providers/google/d/datasource_cloudfunctions_function.html

enhancement sizS

Most helpful comment

Just kidding, I can read. Reopening for a bit more detailed response later on how to remove the binding.

All 6 comments

Hey @JordanStebbings! We actually have an example of how to do this in our docs: https://www.terraform.io/docs/providers/google/r/cloudfunctions_function.html. Take a look at the first example :)

Just kidding, I can read. Reopening for a bit more detailed response later on how to remove the binding.

Hey Dana, thanks for the response, I will describe what I have tried below:

To replicate what I have test please use the follow:

1) Create a Google Cloud Function with Python 3.7, keep everything the default settings however under Authentication Untick the Checkbox for Allow Unauthenticated Invocations

2) When the function is deployed, click the HTTP Trigger and you should receive the message:

"Your client does not have permission to get URL /CLOUD_FUNCTION_NAME from this server."\

3) Visit the Cloud Function Details page, click Source and Download Zip to get a copy of the default Python 3.7 functionality. Put this into the root of your new terraform module and save it as "function-source-terraform-test.zip"

4) Deploy the following terraform functionality by running terraform init, plan, apply:

provider "google" {
  project = "YOUR PROJECT NAME"
  region = "YOUR PROJECT REGION"
  zone = "YOUR PROJECT ZONE"
  credentials = "YOUR DEFAULT CREDENTIALS / PATH TO FILE"
}

resource "google_storage_bucket" "resource-storage" {
    name = "temp-gcf-code"
}

resource "google_storage_bucket_object" "storage-object-code-api" {
  bucket = google_storage_bucket.resource-storage.name
  name = "index-api.zip"
  source = "function-source-terraform-test.zip"
}

resource "google_cloudfunctions_function" "function-api" {
  name = "test-invocation-terraform"
  runtime = "python37"
  timeout = 540
  trigger_http = true
  entry_point = "hello_world"
  source_archive_bucket = google_storage_bucket.resource-storage.name
  source_archive_object = google_storage_bucket_object.storage-object-code-api.name
}

# IAM entry for a single user to invoke the function
resource "google_cloudfunctions_function_iam_member" "invoker" {
  project        = google_cloudfunctions_function.function-api.project
  region         = google_cloudfunctions_function.function-api.region
  cloud_function = google_cloudfunctions_function.function-api.name

  role   = "roles/cloudfunctions.invoker"
  member = "user:[email protected]" / "serviceAccount:SERVICE_ACCOUNT"
}

5) Visit the URL that the new Cloud Function is deployed from, you will be able to see: "Hello World!"

Also just been looking at the Gcloud documentation for deploying Cloud Functions, there is a Flag which can be set for --allow-unauthenticated, could this be replicated for this?

https://cloud.google.com/sdk/gcloud/reference/functions/deploy

@JordanStebbings when you create a function through google_cloudfunctions_function, the provider calls api service https://cloud.google.com/functions/docs/reference/rest/v1/projects.locations.functions/create. Currently by default, api creates google_cloudfunctions_function and implicitly creates an iam object which binds allUsers to roles/cloudfunctions.invoker role. These are all done inside API service. At the provider level, currently there is no code yet that can disable the default iam object creation. To work around this in order to achieve disable unauthenticated invocation, you may create google_cloudfunctions_function_iam_policy, similar to below code, to override that default iam object.

data "google_iam_policy" "admin" {
  binding {
    role = "roles/viewer"
    members = [
      "serviceAccount:[email protected]",
    ]
  }
}

resource "google_cloudfunctions_function_iam_policy" "editor" {
  project = google_cloudfunctions_function.function.project
  region = google_cloudfunctions_function.function.region
  cloud_function = google_cloudfunctions_function.function.name
  policy_data = data.google_iam_policy.admin.policy_data
}

@c2thorn Please note As of January 15, 2020, HTTP functions require authentication by default. (https://cloud.google.com/functions/docs/securing/managing-access-iam) We'd better update the provider code accordingly.

@JordanStebbings when you create a function through google_cloudfunctions_function, the provider calls api service https://cloud.google.com/functions/docs/reference/rest/v1/projects.locations.functions/create. Currently by default, api creates google_cloudfunctions_function and implicitly creates an iam object which binds allUsers to roles/cloudfunctions.invoker role. These are all done inside API service. At the provider level, currently there is no code yet that can disable the default iam object creation.

This is correct, until a while ago allUsers was added by default to any cloud function created, which required explicit removal.

To work around this in order to achieve disable unauthenticated invocation, you may create google_cloudfunctions_function_iam_policy, similar to below code, to override that default iam object.

A less elegant but likely more self-explanatory way to go about this at the time was to explicitly remove the IAM binding.

resource "null_resource" "rm-iam-unauthenticated-invocations" {
  depends_on = [google_cloudfunctions_function.myfunction]
  provisioner "local-exec" {
    command = " gcloud beta functions --project=${var.project} remove-iam-policy-binding ${google_cloudfunctions_function.myfunction.name} --member=\"allUsers\" --role=\"roles/cloudfunctions.invoker\";"
  }
 triggers = { timestamp = "${timestamp()}" }
}

@c2thorn Please note As of January 15, 2020, HTTP functions require authentication by default. (https://cloud.google.com/functions/docs/securing/managing-access-iam) We'd better update the provider code accordingly.

Also, the documentation has been updated accordingly at some point this year:

image

Was this page helpful?
0 / 5 - 0 ratings