首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Terraform为GCP中的多个服务帐户分配多个角色?

如何使用Terraform为GCP中的多个服务帐户分配多个角色?
EN

Stack Overflow用户
提问于 2022-09-27 15:24:08
回答 2查看 255关注 0票数 2

我有一个将要创建的服务帐户列表,为了将角色分配给它们,我使用了一个Google提供的模块,我的代码如下:

代码语言:javascript
复制
module "service-accounts" {
  source  = "terraform-google-modules/service-accounts/google"
  version = "4.1.1"

  project_id = var.project
  names = var.sa_list
  project_roles = [
    "${var.project}=>roles/appengine.appAdmin",
    "${var.project}=>roles/artifactregistry.reader",
    "${var.project}=>roles/cloudbuild.builds.builder",
    "${var.project}=>roles/cloudsql.client",
    "${var.project}=>roles/cloudsql.instanceUser"
  ]

  display_name = "Google App Engine SA - Managed by Terraform"
} 

这个很好用。但是我不想让project_roles中的角色显式化,所以我尝试使用for_each元参数“

variables.tf

代码语言:javascript
复制
variable "rolesList" {
  type =list(string)
  default = ["roles/appengine.appAdmin","roles/artifactregistry.reader", "roles/cloudbuild.builds.builder", "roles/cloudsql.client", "roles/cloudsql.instanceUser"]
}

main.tf

代码语言:javascript
复制
module "service-accounts" {
  source  = "terraform-google-modules/service-accounts/google"
  version = "4.1.1"

  project_id = var.project
  names = var.sa_list

  for_each = (toset[var.rolesList])
  project_roles = ["${var.project}=>${each.key}"]

  display_name = "Google App Engine SA - Managed by Terraform"
} 

这种方式无法工作,因为Terraform将使用相同的id创建多个帐户。如何从project_roles中删除硬代码?有没有办法把角色储存在其他地方,然后再打电话给他们?还是我需要单独分配角色?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-27 21:39:26

如果您想给许多服务帐户赋予多个角色,您可以尝试使用来自官方Google提供商的资源:

首先,将您想要创建的服务帐户像JSON文件一样放在一个配置文件中,这样可以在修改时更加灵活。您将更改配置文件,而不是Terraform代码:

代码语言:javascript
复制
{
  "servicesAccount": {
    "first-service-account": {
      "account_id": "first-service-account",
      "display_name": "First SA managed by Terraform",
  "roles": [
        "roles/appengine.appAdmin",
        "roles/artifactregistry.reader",
        "roles/cloudbuild.builds.builder",
        "roles/cloudsql.client",
        "roles/cloudsql.instanceUser"
      ]
    },
    "second-service-account": {
      "account_id": "second-service-account",
      "display_name": "Second SA managed by Terraform",
  "roles": [
        "roles/appengine.appAdmin",
        "roles/artifactregistry.reader",
        "roles/cloudbuild.builds.builder",
        "roles/cloudsql.client",
        "roles/cloudsql.instanceUser"
      ]
    }
  }
}

然后您可以解析这个JSON文件并放入一个局部变量:

代码语言:javascript
复制
locals {
  services_account = jsondecode(file("${path.module}/path/to/your/file.json"))["servicesAccount"]
  sa_flattened = flatten([
    for sa in local.services_account : [
      for role in sa["roles"] : {
        account_id   = sa["account_id"]
        display_name = sa["display_name"]
        role         = role
      }
    ]
  ])
}

最后,您可以创建SA,然后赋予它们相关的角色:

代码语言:javascript
复制
resource "google_service_account" "sa_names" {
  project      = var.project
  for_each     = local.services_account
  account_id   = each.value["account_id"]
  display_name = each.value["display_name"]
}

resource "google_project_iam_member" "sa_roles" {
  depends_on = [google_service_account.sa_names]
  for_each   = {for idx, sa in local.sa_flattened: "${sa["account_id"]}_${sa["role"]}" => sa}
  project    = var.project
  role       = each.value["role"]
  member     = "serviceAccount:${each.value["account_id"]}@${var.project}.iam.gserviceaccount.com"
}
票数 5
EN

Stack Overflow用户

发布于 2022-09-28 17:50:21

因此,我设法通过更改

代码语言:javascript
复制
variable "rolesList" {
  type =list(string)
  default = ["roles/appengine.appAdmin","roles/artifactregistry.reader", 
             "roles/cloudbuild.builds.builder", "roles/cloudsql.client", 
             "roles/cloudsql.instanceUser"]
     }

代码语言:javascript
复制
 variable "rolesList" {
      type =setstring)
      default = ["roles/appengine.appAdmin","roles/artifactregistry.reader", 
                 "roles/cloudbuild.builds.builder", "roles/cloudsql.client", 
                 "roles/cloudsql.instanceUser"]
         }

以及删除for_each,以利于

代码语言:javascript
复制
module "service-accounts" {
  source  = "terraform-google-modules/service-accounts/google"
  version = "4.1.1"

  project_id = var.project
  names = var.sa_list
  project_roles = [ for role in var.rolesList : "${var.project}=>${role}" ]

  display_name = "Google App Engine SA - Managed by Terraform"
} 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73870071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档