【问题标题】:Terraform: how to iterate over key-value pairs of map input via json fileTerraform:如何通过 json 文件迭代地图输入的键值对
【发布时间】:2021-01-17 17:33:31
【问题描述】:

这是我的输入 json 文件:

{
  "inputs": [
        {
          "acct_id": "foo-bar-15",
          "display_name": "foo bar",
          "project-role-pairs": {"test-1234": "roles/logging.logWriter", "test-2345": "roles/storage.objectViewer"}
        },
        {
          "acct_id": "foo-bar-16",
          "display_name": "john doe",
          "project-role-pairs": {"test-3456": "roles/logging.logWriter", "test-4567": "roles/storage.objectViewer"}
        }
      ]
}

代码: 这是我根据输入在 GCP 中创建服务帐户的代码(该部分工作正常)。它还尝试根据上面 json 文件中的 project-roles-pairs 映射在 2 个项目中创建 IAM 角色。我无法在地图上进行交互。我根本不知道为什么。就目前而言,代码只是将映射中的第一个键用于两者,就好像没有第二对键值对一样。我已经寻找“扁平化”和动态块和setproduct。它们似乎不适合用例,或者我无法有效地使用它们。请帮忙。

locals {
  json_data_7 = jsondecode(file("./data7.json"))
}


# Creates a Service Account for each top level in input
resource "google_service_account" "service_accounts_for_each_7" {
  for_each = {for v in local.json_data_7.inputs: v.acct_id => v.display_name}
  account_id   = each.key
  display_name = each.value
}

# 
resource "google_project_iam_member" "rolebinding" {
  for_each     = { for v in local.json_data_7.inputs: v.acct_id => v }
  project = element(keys(each.value.project-role-pairs),0)  #ONLYfirst key in MAP , not what I want, I would like this part loop through map and create a role for each KV-pair in JSON input
  role    = lookup(each.value.project-role-pairs,element(keys(each.value.project-role-pairs),0))
  member  = "serviceAccount:${google_service_account.service_accounts_for_each_7[each.key].email}"
}

问题:

如何让我的代码遍历 JSON 文件中的 project-roles-pairs 中输入的 2 个键值对?谢谢。

【问题讨论】:

    标签: json foreach terraform terraform-provider-gcp


    【解决方案1】:

    如果我理解正确,您需要对inputsproject-role-pairs 进行两次迭代。因此,您可以先创建一个helper_list,如下所示:

    locals {
    
      helper_list = flatten([ for v in local.json_data_7.inputs: 
                [ for project, role in v.project-role-pairs:
                 { "project" = project
                   "role" = role
                    acct_id = v.acct_id
                    display_name = v.display_name}
                ]
              ])
    }
    

    以上将导致helper_list 成为:

    [
      {
        "acct_id" = "foo-bar-15"
        "display_name" = "foo bar"
        "project" = "test-1234"
        "role" = "roles/logging.logWriter"
      },
      {
        "acct_id" = "foo-bar-15"
        "display_name" = "foo bar"
        "project" = "test-2345"
        "role" = "roles/storage.objectViewer"
      },
      {
        "acct_id" = "foo-bar-16"
        "display_name" = "john doe"
        "project" = "test-3456"
        "role" = "roles/logging.logWriter"
      },
      {
        "acct_id" = "foo-bar-16"
        "display_name" = "john doe"
        "project" = "test-4567"
        "role" = "roles/storage.objectViewer"
      },
    ]
    

    随后,您的google_project_iam_member 可能是:

    resource "google_project_iam_member" "rolebinding" {
      for_each     = { for idx, v in local.helper_list: idx => v }
      project = each.value.project
      role    = each.value.role
      member  = "serviceAccount:${google_service_account.service_accounts_for_each_7[each.value.acct_id].email}"
    }
    

    请注意,以上可能需要调整,因为我通常不使用 GCP,因此我无法验证 google_project_iam_member 应该是什么样子。

    【讨论】:

    • @Mamun 没问题。让我知道进展如何。
    • 就像一个零修改的魅力!绝对精彩!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    相关资源
    最近更新 更多