У меня есть переменная карты
variable "tiers" {
default = {
DEMO_APP = {
env = "demo"
sg = "tier-f5b5d2b4"
}
DEMO_DB = {
env = "demo"
sg = "tier-5425ce73"
}
DEV_APP = {
env = "dev"
sg = "tier-8e96a095"
}
DEV_DB = {
env = "dev"
sg = "tier-3ac50a95"
}
QA_APP = {
env = "qa"
sg = "tier-a176357f"
}
QA_DB = {
env = "qa"
sg = "tier-0d05fa93"
}
}
description = "Map of security group IDs"
type = map(object({
env = string
sg = string
}))
}
Мне нужно добавить к нему поле, которое сопоставляется со списком, созданным объектом данных.
data "loadbalancer" "lbs" {
subproject = subproject.id
}
В конечном результате каждый элемент карты должен иметь дополнительный атрибут «lb»:
DEMO_APP = {
env = "demo"
sg = "tier-f5b5d2b4"
lb = "lb-8956l096"
}
Новый элемент отображается на основе значения env, поэтому каждый env = «demo» будет иметь одно и то же значение lb.
Я предпринял несколько попыток добиться этого, но, покопавшись, я пришел к тому, что сгладил структуру примерно так:
locals {
App_LBs = flatten([
for keys, values in var.tiers : {
name = keys
env = values.env
sg = values.sg
lb = join("",
[
for each in data.loadbalancer.lbs.results : each.id if each.name == "${var.lb_prefix}-${values.env}"
])
}
])
}
Я надеялся, что это решение создаст что-то вроде:
{
name = "DEMO_APP"
env = "demo"
sg = "tier-f5b5d2b4"
lb = "lb-8956l096"
}
{
name = DEMO_DB
env = "demo"
sg = "tier-5425ce73"
lb = "lb-8956l096"
}
К сожалению, при работе с for_each это не удается, поскольку это значение кортежа. Есть ли лучший способ просто добавить этот элемент в массив или, возможно, превратить его во что-то, что будет принимать for_each?
Из выбранного ответа я смог соединить это, чтобы это заработало:
tiers_with_load_balancers = {
for tier, attributes in var.tiers :
tier => merge(attributes,
{
lb = join("",
[
for each in data.loadbalancer.lbs.results : each.id if each.name == "${var.lb_prefix}-${attributes.env}"
])
})
}
Вы можете использовать функцию слияния , чтобы добавлять свойства к существующим элементам.
Пример:
variable "tiers" {
default = {
DEMO_APP = {
env = "demo"
sg = "tier-f5b5d2b4"
}
DEMO_DB = {
env = "demo"
sg = "tier-5425ce73"
}
DEV_APP = {
env = "dev"
sg = "tier-8e96a095"
}
DEV_DB = {
env = "dev"
sg = "tier-3ac50a95"
}
QA_APP = {
env = "qa"
sg = "tier-a176357f"
}
QA_DB = {
env = "qa"
sg = "tier-0d05fa93"
}
}
description = "Map of security group IDs"
type = map(object({
env = string
sg = string
}))
}
locals {
# Hard-coded value used for demonstration purposes only,
# replace it with proper value
load_balancer = "lb-8956l096"
tiers_with_load_balancers = {
for tier, attributes in var.tiers :
tier => merge(attributes, {
lb = local.load_balancer # <-------------------- New property
})
}
}
output "tiers_with_load_balancers" {
value = local.tiers_with_load_balancers
}
Бегу terraform plan
:
Changes to Outputs:
+ tiers_with_load_balancers = {
+ DEMO_APP = {
+ env = "demo"
+ lb = "lb-8956l096"
+ sg = "tier-f5b5d2b4"
}
+ DEMO_DB = {
+ env = "demo"
+ lb = "lb-8956l096"
+ sg = "tier-5425ce73"
}
+ DEV_APP = {
+ env = "dev"
+ lb = "lb-8956l096"
+ sg = "tier-8e96a095"
}
+ DEV_DB = {
+ env = "dev"
+ lb = "lb-8956l096"
+ sg = "tier-3ac50a95"
}
+ QA_APP = {
+ env = "qa"
+ lb = "lb-8956l096"
+ sg = "tier-a176357f"
}
+ QA_DB = {
+ env = "qa"
+ lb = "lb-8956l096"
+ sg = "tier-0d05fa93"
}
}
@ChrisBatchelor, без проблем :-) Может быть, стоит отредактировать свой вопрос, добавив внизу фрагмент кода, который вы только что вставили сюда? Возможно, это будет полезно кому-то в будущем.
Спасибо, я рассмотрел функцию слияния, но не смог заставить ее работать. Однако я смог использовать ваш пример, чтобы что-то получить. ``` tiers_with_load_balancers = { для уровня, атрибуты в var.tiers : tier => merge(attributes, { lb = join("", [ foreach in data.loadbalancer.lbs.results :each.id ifeach.name = = "${var.lb_prefix}-${attributes.env}" ]) }) } ```