如何为我的云功能授权非默认运行时服务帐户?

How do I authorize a non default runtime service account for my cloud function?

我正在使用 terraform 部署 Google Cloud Function。我有一个用于部署云功能的模块,我是这样使用的:

resource "google_storage_bucket" "functions_bucket" {
  name = "${var.project}-functions"
}

module cf {
  source                = "./modules/CloudFunction"
  name                  = "helloworld"
  bucket                = google_storage_bucket.functions_bucket.name
  project               = var.project
  region                = var.region
  service_account_email = "serviceAccount:${google_service_account.sa.email}"
  source_root_dir       = "./cloudFunctions/hello"
  entry_point           = "main"
  runtime               = "python37"
  source_files          = ["main.py","requirements.txt"]
  trigger_http          = true
}

(模块负责压缩函数的源代码并将其上传到存储桶,然后再创建函数)

如上所示,我使用的是非默认 运行 时间服务帐户 service_account_email = "serviceAccount:${google_service_account.sa.email}",该功能将 运行 作为。以下是服务帐户的定义方式:

resource "google_service_account" "sa" {
  account_id = "dataflowdemo"
}

当我 运行 terraform apply 时(即当我想在我的 GCP 项目中创建这些资源时)它失败了。这是输出:

➜ terraform apply --auto-approve
module.cf.data.template_file.t_file1: Refreshing state...
module.cf.data.template_file.t_file[0]: Refreshing state...
module.cf.local_file.to_temp_dir1: Refreshing state... [id=ba8ab5a0280b953aa97435ff8946cbcbb2755a27]
module.cf.local_file.to_temp_dir[0]: Refreshing state... [id=4f74e1a2f443086112a0beca8bd67308e98b3040]
google_storage_bucket.functions_bucket: Refreshing state... [id=myproject-functions]
google_service_account.sa: Refreshing state... [id=projects/myproject/serviceAccounts/dataflowdemo@myproject.iam.gserviceaccount.com]
module.cf.google_storage_bucket_object.archive: Refreshing state... [id=myproject-functions-cloudfunctions/helloworld.f6f6a551ec2a74bbabe74715a20e7c4e.zip]
module.cf.data.archive_file.archive: Refreshing state...
module.cf.google_storage_bucket_object.archive: Destroying... [id=myproject-functions-cloudfunctions/helloworld.f6f6a551ec2a74bbabe74715a20e7c4e.zip]
module.cf.google_storage_bucket_object.archive: Destruction complete after 1s
module.cf.google_storage_bucket_object.archive: Creating...
module.cf.google_storage_bucket_object.archive: Creation complete after 0s [id=myproject-functions-cloudfunctions/helloworld.f6f6a551ec2a74bbabe74715a20e7c4e.zip]
module.cf.google_cloudfunctions_function.HTTPcloudfunction[0]: Creating...

Error: googleapi: Error 400: Invalid function service account requested: serviceAccount:dataflowdemo@myproject.iam.gserviceaccount.com. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation., badRequest

我按照错误消息中提供的 link 找到了此错误消息 (https://cloud.google.com/functions/docs/troubleshooting#non-default-runtime) 的相关部分,其中指出:

to use a non-default runtime service account, the deployer must have the iam.serviceAccounts.actAs permission on that non-default account. A user who creates a non-default runtime service account is automatically granted this permission, but other deployers must have this permission granted by a user with the correct permissions.

解决方案是:

Assign the user the roles/iam.serviceAccountUser role on the non-default runtime service account.

我很困惑为什么这不起作用,因为它指出:

A user who creates a non-default runtime service account is automatically granted this permission

部署者是我(即我的 Google 帐户)。

希望这里有人向我解释我需要做什么才能完成这项工作。 TIA.

当前状态的代码在这里:https://github.com/jamiekt/dataflowdemo/tree/9c3b22f741dc4a48f6180726a8c032c879787f6e

感谢评论者@John-Hanley 提供的帮助。我需要创建一个专用服务帐户来根据 Google Provider > Adding credentials.

进行部署
export PROJECT=myproject
gcloud iam service-accounts create --project $PROJECT deployer
export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/deployer.json
gcloud iam service-accounts keys create \
   --project $PROJECT \
   --iam-account deployer@${PROJECT}.iam.gserviceaccount.com $GOOGLE_APPLICATION_CREDENTIALS
gcloud projects add-iam-policy-binding $PROJECT \
  --member="serviceAccount:deployer@${PROJECT}.iam.gserviceaccount.com" \
  --role="roles/cloudfunctions.admin"
gcloud projects add-iam-policy-binding $PROJECT \
  --member="serviceAccount:deployer@${PROJECT}.iam.gserviceaccount.com" \
  --role="roles/iam.serviceAccountAdmin"
gcloud iam service-accounts add-iam-policy-binding ${PROJECT}@appspot.gserviceaccount.com \
    --member="serviceAccount:deployer@${PROJECT}.iam.gserviceaccount.com" \
    --role=roles/iam.serviceAccountUser