Кортеж Terraform для сопоставления с удалением пустых объектов?

Я пытаюсь создать локальную переменную для цикла for_each в другом ресурсе, но не могу создать локальную карту, как ожидалось.

Вот что я пробовал. (Terraform 0,12)

Ожидается зацикливание карты

temple_list = { "test2-role" = "test-test2-role", ... }

main.tf

locals {
  tmpl_list = flatten([ 
    for role in keys(var.roles) : {
      for tmpl_vars in values(var.roles[role].tmpl_vars) : 
        role => "test-${role}" if tmpl_vars == "SECRET"
    }
  ])
}

output "tmpl_list" {
  value = local.tmpl_list
}

variable "roles" {
    type = map(object({
        tmpl_vars = map(string)
        tags = map(string)
    }))
    
    default = {
        "test-role" = {
            tmpl_vars = {test = "y"}
            tags = { test = "xxx"}
        }
            "test2-role" = {
            tmpl_vars = { token = "SECRET" }
            tags = {}
        }
        "test3-role" = {
            tmpl_vars = {test = "x"}
            tags = {}
        }
    }
}

Ошибка возникает из-за слияния

    | var.roles is map of object with 3 elements

Call to function "merge" failed: arguments must be maps or objects, got
"tuple".

Без слияния

locals {
  tmpl_list = flatten([ 
    for role in keys(var.roles) : {
      for tmpl_vars in values(var.roles[role].tmpl_vars) : 
        role => "test-${role}" if tmpl_vars == "SECRET"
    }
  ])
}

output "tmpl_list" {
  value = local.tmpl_list
}

variable "roles" {
    type = map(object({
        tmpl_vars = map(string)
        tags = map(string)
    }))
    
    default = {
        "test-role" = {
            tmpl_vars = {test = "y"}
            tags = { test = "xxx"}
        }
            "test2-role" = {
            tmpl_vars = { token = "SECRET" }
            tags = {}
        }
        "test3-role" = {
            tmpl_vars = {test = "x"}
            tags = {}
        }
    }
}

Результат отсутствия слияния

tmpl_list = [
  {},
  {
    "test2-role" = "test-test2-role"
  },
  {},
]

Я пробовал другие функции, такие как tomap (), но, похоже, у меня они не работают. (Также я не уверен, почему создаются пустые.)

Как преобразовать этот кортеж в карту без пустых?


person kevmando    schedule 03.09.2020    source источник


Ответы (1)


Сделать это можно в два этапа:

  1. Преобразуйте его в отфильтрованный список объектов:
locals {  
  result = flatten([
    for role, role_value in var.roles: [
      for tmpl_vars in role_value.tmpl_vars: {
        key = role
        value = "test-${role}"
      } if tmpl_vars == "SECRET"
    ]
  ])
}

local.result будет иметь следующее значение:

[
  {
    "key" = "test2-role"
    "value" = "test-test2-role"
  },
]
  1. Затем его легко преобразовать в карту с помощью for:
my_map = { for item in local.result: item.key => item.value }

который дает:

{
  "test2-role" = "test-test2-role"
}
person rkm    schedule 03.09.2020