【问题标题】:Transform an object (map) into a distinct list with terraform使用 terraform 将对象(地图)转换为不同的列表
【发布时间】:2021-04-09 03:55:21
【问题描述】:

使用 Terraform,是否可以转换类似的对象

locals {
  data = {
    "project1" = {
      user_assigned           = ["user1", "user2", "user3"]
     }
    "project2" = {
      user_assigned           = ["user2", "user3", "user4"]
     }
  }

到类似的输出

user1 = ["project1"]
user2 = ["project1","project2"]
user3 = ["project1","project2"]
user4 = ["project2"]

请注意,数据是具有键(项目)和值(用户分配)映射的对象

【问题讨论】:

    标签: terraform terraform0.12+ terraform0.11


    【解决方案1】:

    这是另一种方法,我分享它以防万一——接受的答案也是一种很好的方法。

    locals {
      data = {
        "project1" = {
          user_assigned = ["user1", "user2", "user3"]
        }
        "project2" = {
          user_assigned = ["user2", "user3", "user4"]
        }
      }
    
      project_user = flatten([
        for proj_name, proj in local.data : [
          for username in proj.user_assigned : {
            project_name = proj_name,
            username     = username
          }
        ]
      ])
    }
    
    output "example" {
      value = {
        for pu in local.project_user :
        pu.username => pu.project_name...
      }
    }
    
    Outputs:
    
    example = {
      "user1" = [
        "project1",
      ]
      "user2" = [
        "project1",
        "project2",
      ]
      "user3" = [
        "project1",
        "project2",
      ]
      "user4" = [
        "project2",
      ]
    }
    

    我通常使用这种方法,因为像中间 local.project_user 值这样的数据结构——它是一个包含每个项目/用户对的元素的列表——通常最终在声明代表这些配对的资源时很有用.

    关于这些项目和用户代表什么或他们可能与哪个提供商相关的问题中没有任何上下文,因此我将使用github_teamgithub_team_membership 作为示例来说明我的意思:

    resource "github_team" "example" {
      for_each = local.data
    
      name = each.key
    }
    
    resource "github_team_membership" "example" {
      for_each = {
        for pu in local.project_user : "${pu.username}:${pu.project_name}" => pu
      }
    
      team_id  = github_team.example[each.value.project_name].id
      username = each.value.username
    }
    

    许多提供者都有代表两个对象之间关系的资源,因此拥有一个包含每对元素的中间数据结构对于这些情况来说是一个有用的构建块,然后您可以从该映射派生就像我在原始 sn-p 中的 output "example" 中所做的那样。

    【讨论】:

      【解决方案2】:

      您不能动态创建完全独立的变量。相反,您可以通过几种方式创建地图。一种方法是在transposezipmap 的帮助下:

      output "test1" {
          value = transpose(zipmap(keys(local.data), values(local.data)[*].user_assigned))
      }
      

      导致:

      test1 = tomap({
        "user1" = tolist([
          "project1",
        ])
        "user2" = tolist([
          "project1",
          "project2",
        ])
        "user3" = tolist([
          "project1",
          "project2",
        ])
        "user4" = tolist([
          "project2",
        ])
      })
      

      【讨论】:

      • 非常感谢,这行得通。但是我无法获得“$ {each.value}”,因为它是一个字符串列表。请问有什么办法吗? ` 资源 "local_file" "foo" { for_each = transpose(zipmap(keys(local.data), values(local.data)[*].user_assigned)) 内容 = "${each.value}" 文件名 = "${每个.key}" } `
      • @Devopsnoob 没问题。我建议使用相关代码示例提出新问题,错误消息格式正确(不在 cmets 中),因为这似乎是一个新问题。
      猜你喜欢
      • 2020-11-21
      • 1970-01-01
      • 2019-06-09
      • 2020-11-17
      • 2021-03-18
      • 2019-12-05
      • 1970-01-01
      相关资源
      最近更新 更多