GCP上Terraform身份模拟失败:获取AccessToken权限缺失
我正在为公司现有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.tokengenprovider使用的是执行Terraform的身份(本地个人账号/CloudBuild SA),确保该身份拥有:- 目标SA的
roles/iam.serviceAccountTokenCreator权限 - 足够的权限去获取SA的AccessToken(无额外限制)
- 目标SA的
测试基础权限
用执行身份直接调用GCP API测试模拟权限,比如:gcloud auth print-access-token --impersonate-service-account=tf-sa@your-project.iam.gserviceaccount.com如果该命令返回403,说明身份确实没有模拟权限,需重新检查IAM配置;如果成功,再排查Terraform配置问题。
内容的提问来源于stack exchange,提问作者Gabriele B

