使用服务账号Impersonation跨Terraform后端拉取远程状态遭403拒绝
GCP Terraform跨环境远程状态访问权限问题
项目结构
terraform-project |--base |--main.tf |--input.tf |--input.tfvars |--outputs.tf |--dev |--main.tf |--input.tf |--input.tfvars |--outputs.tf
背景说明
项目包含base和dev两个环境:
base环境通过真实用户user_1模拟服务账号terraform-super-admin创建了远程状态存储桶,其backend配置如下:
terraform { backend "gcs" { bucket = "base-state-bucket" prefix = "terraform.tfstate" impersonate_service_account = "terraform-super-admin@<redacted_project_id>.iam.gserviceaccount.com" } }
状态文件已成功存储至gs://base-state-bucket/terraform.tfstate/default.tfstate。
dev环境需要拉取base的远程状态,因此在dev/main.tf中添加了以下数据块:
data "terraform_remote_state" "base" { backend = "gcs" config = { bucket = "base-state-bucket" prefix = "terraform.tfstate" } }
执行错误
以user_1身份通过gcloud auth login application-default登录后,执行terraform plan出现403权限错误:
data.terraform_remote_state.base: Reading... ╷ │ Error: Error loading state error │ │ with data.terraform_remote_state.base, │ on backend.tf line 11, in data "terraform_remote_state" "base": │ 11: backend = "gcs" │ │ error loading the remote state: Failed to open state file at gs://base-state-bucket/terraform.tfstetate/default.tfstate: │ googleapi: got HTTP response code 403 with body: <?xml version='1.0' encoding='UTF-8'?><Error><Code>AccessDenied</Code><Message>Access │ denied.</Message><Details>user_1 does not have storage.objects.get access to the Google Cloud Storage object.</Details></Error>
疑问
- 为什么模拟
terraform-super-admin的user_1无法获取状态文件? terraform_remote_state数据块是否没有使用服务账号模拟?- 如何在
dev环境中复用basebackend定义的服务账号模拟配置?
已尝试的无效方案
- 使用超级管理员用户
super_user_alpha通过gcloud auth login application-default登录后执行terraform plan,仍报user_1的403权限错误; - 执行
gcloud auth revoke user_1撤销权限后,执行terraform plan仍出现403错误,但未显示被拒绝用户信息。
解决方案
1. 为user_1添加服务账号模拟权限
user_1需要拥有模拟terraform-super-admin服务账号的权限,执行以下命令授予roles/iam.serviceAccountTokenCreator角色:
gcloud projects add-iam-policy-binding <redacted_project_id> \ --member="user:user_1@yourdomain.com" \ --role="roles/iam.serviceAccountTokenCreator" \ --service-account="terraform-super-admin@<redacted_project_id>.iam.gserviceaccount.com"
2. 在dev的远程状态数据块中配置服务账号模拟
base环境的backend模拟配置不会自动被dev的terraform_remote_state继承,需要在数据块中显式添加impersonate_service_account参数:
data "terraform_remote_state" "base" { backend = "gcs" config = { bucket = "base-state-bucket" prefix = "terraform.tfstate" impersonate_service_account = "terraform-super-admin@<redacted_project_id>.iam.gserviceaccount.com" } }
3. 清理并重新配置应用默认凭据
之前的错误可能源于缓存的旧凭据,执行以下命令重置:
# 撤销现有应用默认凭据 gcloud auth application-default revoke # 以user_1身份登录后模拟服务账号 gcloud auth login user_1@yourdomain.com gcloud config set auth/impersonate_service_account terraform-super-admin@<redacted_project_id>.iam.gserviceaccount.com
或者直接用服务账号模拟登录应用默认凭据:
gcloud auth application-default login --impersonate-service-account=terraform-super-admin@<redacted_project_id>.iam.gserviceaccount.com
内容的提问来源于stack exchange,提问作者Imad
相关产品推荐
相关产品推荐

