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

GCP上Terraform身份模拟失败:获取AccessToken权限缺失

Terraform模拟服务账号时触发403权限错误(iam.serviceAccounts.getAccessToken)

我正在为公司现有Terraform脚本搭建CI/CD流水线,用高权限账号本地执行完全正常,但远程执行失败,判断是权限问题但无法定位具体位置。

已配置的服务账号IAM角色

为Terraform创建了专用服务账号(SA),并通过以下代码授予组织级角色:

resource "google_organization_iam_member" "org_tf_folder_admin" {
  count  = var.folder_id != "" ? 0 : 1
  org_id = var.org_id
  role   = "roles/resourcemanager.folderAdmin"
  member = "serviceAccount:${module.terraform_project.terraform_sa_email}"
}

resource "google_organization_iam_member" "org_tf_project_creator" {
  count  = var.folder_id != "" ? 0 : 1
  org_id = var.org_id
  role   = "roles/resourcemanager.projectCreator"
  member = "serviceAccount:${module.terraform_project.terraform_sa_email}"
} 

已确认这些角色成功应用到该SA。

Terraform Provider配置

在versions.tf中配置模拟该服务账号:

provider "google" {
  impersonate_service_account = ${module.terraform_project.terraform_sa_email}
}

provider "google-beta" {
  impersonate_service_account = ${module.terraform_project.terraform_sa_email}
}

错误信息

执行时(比如列出组织内文件夹或访问var.folder_id下的项目)触发403错误,本地和CloudBuild环境均出现此问题:

│ Error: Error when reading or editing Folder Not Found : folders/XXXXXXXXXXXX: Get "https://cloudresourcemanager.googleapis.com/v3/folders/XXXXXXXXXXXX?alt=json&prettyPrint=false": impersonate: status code 403: {
│   "error": {
│     "code": 403,
│     "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
│     "status": "PERMISSION_DENIED",
│     "details": [
│       {
│         "@type": "type.googleapis.com/google.rpc.ErrorInfo",
│         "reason": "IAM_PERMISSION_DENIED",
│         "domain": "iam.googleapis.com",
│         "metadata": {
│           "permission": "iam.serviceAccounts.getAccessToken"
│         }
│       }
│     ]
│   }
│ }
│
│
│   with google_folder.env,
│   on main.tf line 37, in resource "google_folder" "env":
│   37: resource "google_folder" "env" {

补充说明1

已为CloudBuild默认服务账号配置模拟权限:

resource "google_service_account_iam_member" "cloudbuild_terraform_sa_impersonate_permissions" {
  service_account_id = var.terraform_sa_name
  role               = "roles/iam.serviceAccountTokenCreator"
  member             = "serviceAccount:${module.cloudbuild_project.project_number}@cloudbuild.gserviceaccount.com"
}

但本地用个人身份执行也失败,问题不在CloudBuild配置本身。

补充说明2

尝试添加显式生成AccessToken的配置,问题依旧:

provider "google" {
  alias = "tokengen"
}

# get config of the client that runs
data "google_client_config" "default" {
  provider = google.tokengen
}

data "google_service_account_access_token" "sa" {
  provider               = google.tokengen
  target_service_account = local.tf_sa
  lifetime               = "600s"
  scopes = [
    "https://www.googleapis.com/auth/cloud-platform",
    "https://www.googleapis.com/auth/userinfo.email",
  ]
}

/******************************************
  GA Provider configuration
 *****************************************/

provider "google" {
  access_token = data.google_service_account_access_token.sa.access_token
}
provider "google-beta" {
  access_token = data.google_service_account_access_token.sa.access_token
}

解决思路

核心问题

错误提示的iam.serviceAccounts.getAccessToken权限,是执行Terraform的身份(本地个人账号/CloudBuild SA)需要拥有的权限,而非目标Terraform SA本身的权限。你虽然给CloudBuild SA配置了roles/iam.serviceAccountTokenCreator(该角色包含上述权限),但本地个人账号没有这个权限,这就是本地执行也失败的原因。

具体解决步骤

  • 给本地执行的个人账号授予模拟权限
    给你的个人GCP账号,在目标Terraform SA上添加roles/iam.serviceAccountTokenCreator角色,可通过GCP控制台或以下Terraform代码实现:

    resource "google_service_account_iam_member" "local_user_impersonate_tf_sa" {
      service_account_id = module.terraform_project.terraform_sa_id
      role               = "roles/iam.serviceAccountTokenCreator"
      member             = "user:your-personal-email@example.com"
    }
    
  • 验证权限传播
    GCP组织级或IAM权限可能存在几分钟的传播延迟,配置完权限后等待5-10分钟再测试。

  • 检查变量引用正确性
    确认module.terraform_project.terraform_sa_email和local.tf_sa变量的取值正确,指向的是目标Terraform SA的完整邮箱(格式:sa-name@project-id.iam.gserviceaccount.com)。

  • 排查显式Token生成配置的问题
    显式生成Token的配置中,google.tokengen provider使用的是执行Terraform的身份(本地个人账号/CloudBuild SA),确保该身份拥有:

    • 目标SA的roles/iam.serviceAccountTokenCreator权限
    • 足够的权限去获取SA的AccessToken(无额外限制)
  • 测试基础权限
    用执行身份直接调用GCP API测试模拟权限,比如:

    gcloud auth print-access-token --impersonate-service-account=tf-sa@your-project.iam.gserviceaccount.com
    

    如果该命令返回403,说明身份确实没有模拟权限,需重新检查IAM配置;如果成功,再排查Terraform配置问题。


内容的提问来源于stack exchange,提问作者Gabriele B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:07:11