Terraform+GCP:配置项目级服务账号Impersonation时遇403错误
GCP服务账号模拟配置的403权限问题
项目结构
terraform-infra-genesis ┣ base ┃ ┣ ... ┃ ┣ impersonators_x_users.tf <- 在此处为用户邮箱me@domain.com授予组织范围内'super-admin'账号的iam.serviceAccounts.getAccessToken角色 ┃ ┣ ... ┃ ┣ providers_x_access_tokens.tf ┃ ┣ service_accounts_x_roles.tf <- 在此处声明'dev-admin'服务账号 ┃ ┣ terraform.tfstate ┃ ┗ terraform.tfstate.backup ┣ dev <- 所有资源属于开发环境 ┃ ┣ backend.tf ┃ ┣ data_products.tf <- 在此处使用'marketing-hub'模块 ┃ ┣ ... ┃ ┣ impersonators_x_providers_x_access_tokens.tf <- 声明as_dev_admin provider,将资源创建权限委托给dev环境超级管理员;同时声明"as_<project>_dev_admin",理论上仅能在对应项目内创建资源 ┣ modules ┃ ┣ data-products ┃ ┃ ┣ cmi ┃ ┃ ┃ ┗ feedback-hub ┃ ┃ ┗ ddm ┃ ┃ ┃ ┣ analytics-hub ┃ ┃ ┃ ┣ marketing-hub ┃ ┃ ┃ ┃ ┣ marketing_hub.tf <- 在此处使用'data-project'模块将所有逻辑项目打包 ┃ ┃ ┃ ┗ media-hub ┃ ┗ data-project ┃ ┃ ┣ data_project.tf <- 此模块用于创建GCP项目及对应的project-dev-admin服务账号 ┣ prod ┃ ┣ ... ┣ .gitignore ┗ README.md
当前配置与问题
已在dev根模块中使用provider = as_dev_admin成功创建dev_coupons GCP项目。dev/impersonators_x_providers_x_access_tokens.tf配置如下:
terraform { required_providers { google = { source = "hashicorp/google" version = ">=3.85.0" } } } locals { tier_1_scopes = [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email", ] tier_2_scopes = [ "cloud-platform", "userinfo-email", ] } # Dev Admin模拟配置 provider "google" { alias = "impersonation" scopes = local.tier_1_scopes } data "google_service_account_access_token" "dev-admin" { provider = google.impersonation target_service_account = data.terraform_remote_state.base.outputs.service-accounts.dev-admin.email scopes = local.tier_2_scopes lifetime = "1200s" } provider "google" { alias = "as_dev_admin" access_token = data.google_service_account_access_token.dev-admin.access_token region = var.region zone = var.zone } ################################################################################ ##################### 服务账号模拟配置 ####################### ############################ as_dev_coupons_admin ############################## ################################################################################ # 复制此块可添加任意服务账号的模拟配置 data "google_service_account_access_token" "dev-coupons-admin" { provider = google.impersonation target_service_account = module.marketing-hub-products.projects.coupons.admin_service_account.email scopes = local.tier_2_scopes lifetime = var.lifetime } provider "google" { alias = "as_dev_coupons_admin" project = module.marketing-hub-products.projects.coupons.project_info.project_id access_token = data.google_service_account_access_token.dev-coupons-admin.access_token region = var.region zone = var.zone } resource "google_service_account_iam_member" "dev-coupons-admin-impersonators" { provider = google.as_dev_admin # 由全局dev环境管理员授予权限 for_each = toset([ for account in var.user_accs_impersonators_info.as_dev_coupons_admin : "${account.acc_type}:${account.acc_details.email}" ]) service_account_id = module.marketing-hub-products.projects.coupons.admin_service_account.name role = "roles/iam.serviceAccountTokenCreator" member = each.value } ################################################################################ ################################### 结束 ##################################### ############################ as_dev_coupons_admin ############################## ################################################################################
尝试添加dev-coupons项目管理员的provider别名as_dev_coupons_admin时,触发以下403错误:
│ Error: googleapi: Error 403: The caller does not have permission, forbidden │ │ with data.google_service_account_access_token.dev-coupons-admin, │ on impersonators_x_providers_x_access_tokens.tf line 48, in data "google_service_account_access_token" "dev-coupons-admin": │ 48: data "google_service_account_access_token" "dev-coupons-admin" { │
排查信息
启用Terraform调试日志(执行export TF_VAR=DEBUG; export TF_LOG_PATH="terraform_log.txt")后,获取到以下请求与响应:
请求详情
---[ REQUEST ]--------------------------------------- POST /v1/projects/-/serviceAccounts/dev-coupons-admin@<redacted_project_id>.iam.gserviceaccount.com:generateAccessToken?alt=json&prettyPrint=false HTTP/1.1 Host: iamcredentials.googleapis.com User-Agent: google-api-go-client/0.5 Terraform/1.2.9 (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google/dev Content-Length: 129 Content-Type: application/json X-Goog-Api-Client: gl-go/1.18.1 gdcl/0.92.0 Accept-Encoding: gzip { "lifetime": "1200s", "scope": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email" ] } -----------------------------------------------------: timestamp=2022-09-21T21:25:58.442+0200
响应详情
2022-09-21T21:25:58.534+0200 [INFO] provider.terraform-provider-google_v4.36.0_x5: 2022/09/21 21:25:58 [DEBUG] Google API Response Details: ---[ RESPONSE ]-------------------------------------- HTTP/2.0 403 Forbidden Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43" Cache-Control: private Content-Type: application/json; charset=UTF-8 Date: Wed, 21 Sep 2022 19:26:04 GMT Server: scaffolding on HTTPServer2 Vary: Origin Vary: X-Origin Vary: Referer X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { "error": { "code": 403, "message": "The caller does not have permission", "errors": [ { "message": "The caller does not have permission", "domain": "global", "reason": "forbidden" } ], "status": "PERMISSION_DENIED" } }
疑问点
- 无法理解为何创建
google_service_account_access_token.dev_coupons_admin会返回403错误,当前dev模块使用的凭据与创建dev环境资源的凭据一致,关联用户邮箱也相同。 - 请求路径中的
/v1/projects/-/serviceAccounts/里的-是否是问题根源?是否意味着请求试图通过指定服务账号访问所有项目?
补充:dev-coupons-admin是dev-coupons项目的所有者。
内容的提问来源于stack exchange,提问作者Imad
相关产品推荐
相关产品推荐

