首页 > 解决方案 > 如何为我的云功能授权非默认运行时服务帐户?

问题描述

我正在使用 terraform 部署 Google Cloud 功能。我有一个用于部署云功能的模块,我使用如下:

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_file 1:刷新状态...
module.cf.data.template_file.t_file[0]:刷新状态...
module.cf.local_file.to_temp_dir 1:刷新状态... [id=ba8ab5a0280b953aa97435ff8946cbcbb2755a27]
module.cf.local_file.to_temp_dir[0]:刷新状态... [id=4f74e1a2f443086112a0beca8bd67308e98b3040]
google_storage_service...[_accountid=project-function]
google_storage_service ...[_accountid=project-function] sa:刷新状态... [id=projects/myproject/serviceAccounts/dataflowdemo@myproject.iam.gserviceaccount.com]
module.cf.google_storage_bucket_object.archive:刷新状态... [id=myproject-functions-cloudfunctions/helloworld.f6f6a551ec2a74bbabe74715a20e7c4e.zip]
module.cf.data.archive_file.archive:刷新状态...
module.cf.google_storage_bucket_object.archive :销毁... [id=myproject-functions-cloudfunctions/helloworld.f6f6a551ec2a74bbabe74715a20e7c4e.zip]
module.cf.google_storage_bucket_object.archive:1s module.cf.google_storage_bucket_object.archive 后销毁完成
:正在创建...
module.cf.google_storage_bucket_object。存档:0s 后创建完成 [id=myproject-functions-cloudfunctions/helloworld.f6f6a551ec2a74bbabe74715a20e7c4e.zip]
module.cf.google_cloudfunctions_function.HTTPcloudfunction[0]:正在创建...

错误:googleapi:错误 400:请求的功能服务帐户无效:serviceAccount:dataflowdemo@myproject.iam.gserviceaccount.com。请访问https://cloud.google.com/functions/docs/troubleshooting以获取深入的故障排除文档。badRequest

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

要使用非默认运行时服务帐户,部署者必须拥有该iam.serviceAccounts.actAs非默认帐户的权限创建非默认运行时服务帐户的用户会被自动授予此权限,但其他部署者必须具有由具有正确权限的用户授予的此权限。

解决方案是:

为用户分配roles/iam.serviceAccountUser 非默认运行时服务帐户的角色。

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

创建非默认运行时服务帐户的用户会自动获得此权限

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

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

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

标签: google-cloud-platformgoogle-cloud-functionsterraformterraform-provider-gcpgoogle-cloud-iam

解决方案


感谢您在这里提供帮助的评论者@John-Hanley。我需要根据Google Provider > 添加凭据创建一个专用服务帐户来进行部署。

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

推荐阅读