You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:30:52