terraform-provider-google: Cannot create CloudFunction with terraform app authorization

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 an 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 an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned to hashibot, a community member has claimed the issue already.

Terraform Version

Terraform v0.12.18 provider.google v2.20.1

Affected Resource(s)

  • google_cloudfunctions_function

Terraform Configuration Files

resource "google_cloudfunctions_function" "cloud-sql-exporter" {
  name    = "cloud-sql-exporter"
  runtime = "python37"

  available_memory_mb   = 256
  source_archive_bucket = google_storage_bucket.functions-code.name
  source_archive_object = google_storage_bucket_object.code-archive.name
  trigger_http          = true
  entry_point           = "main"

  environment_variables = {
    DB_INSTANCE   = "${module.module_name.db_instance_name[0]}",
    BACKUP_BUCKET = "${google_storage_bucket.project-db-backup.name}"
  }
}

Debug Output

Panic Output

Expected Behavior

gcloud function successfully created

Actual Behavior

google cloud function failed to create 

google_cloudfunctions_function.cloud-sql-exporter: Creating...

Error: Error waiting for Creating CloudFunctions Function: error while retrieving operation: googleapi: Error 403: Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the cloudfunctions.googleapis.com. We recommend that most server applications use service accounts instead. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/., accessNotConfigured

  on functions.tf line 28, in resource "google_cloudfunctions_function" "cloud-sql-exporter":
  28: resource "google_cloudfunctions_function" "cloud-sql-exporter" {

Steps to Reproduce

  1. terraform apply

Important Factoids

terraform authenticated as application with gcloud auth application-default login Actually I don’t have any credentials config within terraform. BTW, I have successfully created cloud function couple of weeks ago (before NY2020) with same config, but now I see error. In fact - cloud functions created, but I cannot create dependent resources. I tried different provider versions (3.0.0-beta.1 and 3.4.0) with the same result.

References

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 24
  • Comments: 17 (2 by maintainers)

Most upvoted comments

As @edwardmedia noted, we don’t recommend using gcloud credentials to authenticate to Terraform, because it opens the doors for this exact style of breakages. From https://www.terraform.io/docs/providers/google/guides/provider_reference.html#credentials-1:

On your computer, you can make your Google identity available by running gcloud auth application-default login. This approach isn’t recommended- some APIs are not compatible with credentials obtained through gcloud.

If you can’t use a service account, you should be able to succeed by using an access token, with the important caveat that it will expire. I also can’t guarantee that it won’t at some point end up with a similar error as when using application credentials.

If neither of these are options, then you should obtain end-user credentials using an application that is not gcloud (since its credentials are really meant to be used in gcloud itself). I haven’t tried this myself, but I think it would require setting up an oauth application that you can then get a credentials file from. https://cloud.google.com/docs/authentication/end-user would be the place to look to get started. If you try it, let me know how it goes!

I’ve used the exact same account for the last 5 months (at least). But this issue showed up like a week ago or a bit more.

Error: Error waiting for Deleting CloudFunctions Function: error while retrieving operation: googleapi: Error 403: Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the cloudfunctions.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/., accessNotConfigured

while a service account is clearly suggested. I still don’t get why the error shows up now. Is it a change gcp side? I don’t remember updating any provider.

@flaker indeed this was an API-side change rather than a Terraform one. The comment above yours and the one above that mention some workarounds, so hopefully one of those will work for you. I agree that the behavior is counterintuitive.

For anyone on this thread that’s a Googler or has a Google-side contact, you (/they) can follow b/148479480 for updates.

@schaffino Need audit trail is legit. Let’s see what we can do.

What’s strange about this issue is that the function gets created fine. If you run the deploy a second time it will complete successfully. Using a service account works, but i dislike having service account keys kept around on devs machines. You also lose the audit trail of who has done what. Impersonation works fine too, but again, no audit trail in the logs as to who has actually modified or created infrastructure.

@edwardmedia I tried to use GOOGLE_CLOUD_KEYFILE_JSON with service account “Editor” permissions and it worked. But anyway, is it any possibility to look through the original issue, that cloudfunctions.googleapis.com could not be created via Google APIs Service Agent. I manage tens projects in gcloud and it is not convenient to use service account json for every single project. Thanks.

@edwardmedia thanks for response, I use service account called “Google APIs Service Agent” with name PROJECT_NUMBER@cloudservices.gserviceaccount.com and authenticate with gcloud auth application-default login and actually there is no json key configuration for terraform. I have quite big config and all modules work fine except cloud_functions.

My workaround is to actually call gcloud as a local-exec provisioner. Super janky but it works (only for creation).

resource "null_resource" "status_update" {
  triggers = {
    hash = data.archive_file.functions.output_base64sha256
  }

  provisioner "local-exec" {
    interpreter = ["bash", "-c"]
    command = join(" ", [
      "gcloud functions deploy",
      "${local.function_name}",
      "--project=${var.project}",
      "--region=${var.region}",
      "--runtime=go111",
      "--entry-point=EntryPoint",
      "--trigger-topic=${local.status_update_topic}",
      "--source=gs://${local.function_bucket_name}/${google_storage_bucket_object.functions.name}",
      "--set-env-vars=${local.function_env_vars}",
      "--max-instances=1",
      "--timeout=60",
      "--memory=128MB",
      "<<< 'N\n'",
    ])
  }
}