[英]Terraform & GCP : Error 403 when attempting to introduce impersonation on project-level
在应用启用服务帐户模拟的原则时,我非常迷茫......
我的 terraform 项目结构在每个环境中都有一个根模块,用于基本基础架构的base
,用于开发环境的dev
和用于生产环境的prod
。
terraform-infra-genesis
┣ base
┃ ┣ ...
┃ ┣ impersonators_x_users.tf <- user email me@domain.com is granted iam.serviceAccounts.getAccessToken role on 'super-admin' here (On all the organization)
┃ ┣ ...
┃ ┣ providers_x_access_tokens.tf
┃ ┣ service_accounts_x_roles.tf <- 'dev-admin' service account declared here
┃ ┣ terraform.tfstate
┃ ┗ terraform.tfstate.backup
┣ dev <- Everything here belongs to the dev environment
┃ ┣ backend.tf
┃ ┣ data_products.tf <- Usage of the module 'marketing-hub' here
┃ ┣ ...
┃ ┣ impersonators_x_providers_x_access_tokens.tf <- Declaration of as_dev_admin provider to 'delegate' ressource creation (such as folders) to the dev environment "super" administrator. I also declared "as_<project>_dev_admin" that should in principle, be able to create ressources only within its own <project>
┣ modules
┃ ┣ data-products
┃ ┃ ┣ cmi
┃ ┃ ┃ ┗ feedback-hub
┃ ┃ ┗ ddm
┃ ┃ ┃ ┣ analytics-hub
┃ ┃ ┃ ┣ marketing-hub
┃ ┃ ┃ ┃ ┣ marketing_hub.tf <- Usage of module 'data-project' here to bundle all logical projects together.
┃ ┃ ┃ ┗ media-hub
┃ ┗ data-project
┃ ┃ ┣ data_project.tf <- Module to create a GCP project and its project-dev-admin service account here
┣ 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 impersonation
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
}
################################################################################
##################### Impersonation of a service account #######################
############################ as_dev_coupons_admin ##############################
################################################################################
# Copy/paste this block in order to introduce the
# impersonation of any service account
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 # Global dev environment admin will grant this permission
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
}
################################################################################
################################### End of #####################################
############################ as_dev_coupons_admin ##############################
################################################################################
我的项目名称是dev-coupons
。
当我尝试将附加provider alias as_dev_coupons_admin
声明给特定项目dev-coupons
管理员时,我收到此错误:
│ 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" {
│
我不明白为什么创建"google_service_account_access_token" "dev_coupons_admin"
返回403
......起初,我以为是因为某些父模块的provider
在干扰,但不,这里我们在基本模块dev
,具有相同的创建整个dev
环境资源的凭据,具有相同的关联用户 email,但返回此拒绝访问。
然后我启用了日志export TF_VARS=DEBUG; export TF_LOG_PATH="terraform_log.txt"
export TF_VARS=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"
}
}
也许它正在尝试通过指定的服务帐户访问“所有”项目? 请参阅-
在/v1/projects/-/serviceAccounts/
中?
如果您能够阐明我缺乏理解的地方,我将不胜感激。
编辑: dev-coupons-admin
是dev-coupons
的所有者
TL;DR me@domain.com
有权使用dev
环境超级管理员创建令牌。 这并不意味着正确的级联到同一环境中的项目,您必须将帐户重新声明为与正确的服务帐户关联的令牌创建者。
我想我弄清楚了这个问题。 关键是要了解服务帐户 token_creators 的角色token_creators
。
as_dev_admin
用于创建资源作为默认提供程序。
roles/iam.serviceAccountTokenCreator
的用户 email me@domain.com
通过base
基础结构中的项目关联到此服务帐户,在层次结构中较高,但不是直接父级。 这意味着模拟者的这个角色不会在dev
环境中创建的data-project
中继承。 Once you try to impersonate the dev-coupons-admin@<redacted_project_id>.iam.gserviceaccount.com
using me@domain.com
, it will not transfer to this email account because it was present in dev-admin@<some_common_project_id>.iam.gserviceaccount.com
, dev
超级管理员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.