简体   繁体   English

Terraform 和 GCP:尝试在项目级别引入模拟时出现错误 403

[英]Terraform & GCP : Error 403 when attempting to introduce impersonation on project-level

I am quite lost when it comes to applying principles that enable service account impersonation ...在应用启用服务帐户模拟的原则时,我非常迷茫......

My terraform project structure has a root module per environment, base for basic infrastructure, dev for the dev environment and prod for the production environment.我的 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

As described in the annotations on this structure, I generally use a provider = as_dev_admin within the dev/ root-module.如该结构的注释中所述,我通常在dev/根模块中使用provider = as_dev_admin I successfully created dev_coupons (A GCP project) using it.我使用它成功创建了dev_coupons (一个 GCP 项目)。

Here is the structure of my dev/impersonators_x_providers_x_access_tokens.tf这是我的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 ##############################
################################################################################

My project name is dev-coupons .我的项目名称是dev-coupons

When I try to declare the additionnal provider alias as_dev_coupons_admin to a specific project dev-coupons admin, I get this error:当我尝试将附加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" {
│

I don't understand why creating the "google_service_account_access_token" "dev_coupons_admin" returns a 403 ... At first, I thought it is because some parent module's provider was interfering, but no, here we are at the base module dev , with the same credentials that created the whole dev environment ressources, with the same associated user email, yet this denial of access is returned.我不明白为什么创建"google_service_account_access_token" "dev_coupons_admin"返回403 ......起初,我以为是因为某些父模块的provider在干扰,但不,这里我们在基本模块dev ,具有相同的创建整个dev环境资源的凭据,具有相同的关联用户 email,但返回此拒绝访问。

I then enabled logs export TF_VARS=DEBUG; export TF_LOG_PATH="terraform_log.txt"然后我启用了日志export TF_VARS=DEBUG; export TF_LOG_PATH="terraform_log.txt" export TF_VARS=DEBUG; export TF_LOG_PATH="terraform_log.txt" , and I find this line: 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"
  }
}

Perhaps it is trying to access "all" projects via the designated service account?也许它正在尝试通过指定的服务帐户访问“所有”项目? See - in /v1/projects/-/serviceAccounts/ ?请参阅-/v1/projects/-/serviceAccounts/中?

If you are able to shed some light on where my understanding is lacking, I would greatly appreciate it.如果您能够阐明我缺乏理解的地方,我将不胜感激。

EDIT: dev-coupons-admin is the owner of dev-coupons编辑: dev-coupons-admindev-coupons的所有者

TL;DR me@domain.com has the right to create tokens using a dev environment super admin. TL;DR me@domain.com有权使用dev环境超级管理员创建令牌。 This does not mean that right cascades to projects within this same environment, you have to redeclare the account as token creator associated with the right service account.这并不意味着正确的级联到同一环境中的项目,您必须将帐户重新声明为与正确的服务帐户关联的令牌创建者。

I think I figured out this problem.我想我弄清楚了这个问题。 The key is to understand the inheritance of roles for service account token_creators .关键是要了解服务帐户 token_creators 的角色token_creators

  • Within my organization the as_dev_admin is used to create resources as the default provider.在我的组织中, as_dev_admin用于创建资源作为默认提供程序。
    • There is a service account that has the right for creating the infrastructure elements.有一个服务帐户有权创建基础结构元素。
    • The user email me@domain.com that has the roles/iam.serviceAccountTokenCreator is associated to this service account via a project within the base infrastructre, higher in the hierarchy, but not a direct parent.具有roles/iam.serviceAccountTokenCreator的用户 email me@domain.com通过base基础结构中的项目关联到此服务帐户,在层次结构中较高,但不是直接父级。
    • -> It is apparently erroneous to assume the user associated to service account will have the same right within child elements of the infrastructure. -> 假设与服务帐户关联的用户在基础设施的子元素中具有相同的权限显然是错误的。

This means that this role for the impersonator is not inherited within the data-project created in dev environment.这意味着模拟者的这个角色不会在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 , the dev super admin. 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.comdev超级管理员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Terraform/GCP 错误:项目:未设置必填字段 - Terraform/GCP Error: project: required field is not set Terraform:googleapi:错误 403:资源项目权限被拒绝 - Terraform: googleapi: Error 403: Permission denied on resource project (Terraform,GCP)错误 403:拒绝为消费者容器列出服务的权限 [projects/335478934851] - (Terraform, GCP) Error 403: Permission denied to list services for consumer container [projects/335478934851] terraform 在尝试创建负载均衡器时为 GCP 返回“invalid_grant”,我无法以所有者身份查看或编辑 SA 权限 - terraform returns 'invalid_grant' for GCP when attempting to create load balancer and I cannot view or edit SA permissions as owner GCP 项目间 IAM 与 Terraform - GCP inter-project IAM with terraform 部署 firebase 规则时模拟 GCP 服务帐户 - GCP service account impersonation when deploying firebase rules 使用 Terraform 权限错误在 GCP 上构建 GKE 集群 - Building a GKE cluster on GCP with Terraform permission error Terraform compute.networks.create 的 GCP 错误 - Terraform Error with GCP for compute.networks.create 在 terraform 申请期间遇到错误 403 - running into error 403 during terraform apply 使用 terraform 在 GCP 中为不同的项目 ID 创建计算实例时出现问题 - Problem with creating compute instance in GCP for different project IDs with terraform
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM