Ищете более лаконичный способ выполнения вложенного цикла

#terraform #hcl

#terraform #hcl

Вопрос:

Ищете более чистый / понятный способ создания вложенного цикла в Terraform. Я проиллюстрирую это на примере.

Допустим, у нас есть переменная для ролей, которая выглядит следующим образом:

 variable "roles" {
  type    = "list"
  default = [
    {
      name    = "LOADER"
      schemas = {
        RAW = ["USAGE", "ALL"]
        SRC = ["ALL"]
      }
    },
    {
      name    = "USER"
      schemas = {
        RAW = ["DELETE", "OBJECT"]
        SRC = ["USE"]
      }
    }
  ]
}
 

Исходя из этого, я хочу получить список словарей, который выглядит примерно так:

 output = [
  {
    "privilege" = "USAGE"
    "role" = "LOADER"
    "schema" = "RAW"
  },
  {
    "privilege" = "ALL"
    "role" = "LOADER"
    "schema" = "RAW"
  },
  {
    "privilege" = "ALL"
    "role" = "LOADER"
    "schema" = "SRC"
  },
  {
    "privilege" = "DELETE"
    "role" = "USER"
    "schema" = "RAW"
  },
  {
    "privilege" = "OBJECT"
    "role" = "USER"
    "schema" = "RAW"
  },
  {
    "privilege" = "USE"
    "role" = "USER"
    "schema" = "SRC"
  },
]
 

То, что я пробовал до сих пор (кажется, работает, но я ищу более краткий / читаемый способ сделать это):

 locals {
  # FlatMapping to a list of dictionaries. Each dict in the form of {schema=<schema>, role=<role>, privilege=<privilege>}
  key_val       = [for role in var.roles : [for schema, privilege in role["schemas"]: {
    role      = role["name"]
    schema    = schema
    privilege = privilege
  }]]
  other_key_val = [for dict in flatten(local.key_val): [for priv in dict["privilege"]: {
    role      = dict["role"]
    schema    = dict["schema"]
    privilege = priv
  }]]
}

output "output" {
  value = flatten(local.other_key_val)
}
 

Моя главная цель — иметь читаемый код, который может быть лучше понятен другим. Учитывая, что я впервые использую циклы в Terraform, я не могу судить, считается ли моя реализация читаемой.

Ответ №1:

Возможно, это был бы немного более простой способ добиться того же результата:

 locals {
  roles = [
      {
        name    = "LOADER"
        schemas = {
          RAW = ["USAGE", "ALL"]
          SRC = ["ALL"]
        }
      },
      {
        name    = "USER"
        schemas = {
          RAW = ["DELETE", "OBJECT"]
          SRC = ["USE"]
        }
      }
  ]

  out = flatten([
    for item in local.roles: [
      for schema, privileges in item.schemas: [
        for privilege in privileges: {
          role = item.name
          privilege = privilege
          schema = schema
        }
      ]
    ]
  ])
}