Можно ли ссылаться на другое значение locals внутри создания значения locals?
Приведенный ниже пример был самым маленьким и простым примером, который я смог придумать.
variable "size" {
default = 3
}
variable "infrastructure_version" {
default = 1
}
locals {
values = {
for n in range(var.size) : n => {
name = "instance_${n + 1}"
full_name = "test_${name}_v${var.infrastructure_version}"
}
}
}
При попытке доступа к название в цикле for внутри блока locals я получаю следующую ошибку:
│ Error: Invalid reference
│
│ on instances.tf line 13, in locals:
│ 13: full_name = "test_${name}_v${var.infrastructure_version}"
│
│ A reference to a resource type must be followed by at least one attribute access, specifying the resource name.
Другие попытки: (Это были отчаянные попытки без реальных шансов на успех)
local.values[n].name что дает Error: Self-referencing local valuen.name что дает Error: Unsupported attributeself.name что дает Error: Invalid "self" referenceКто-нибудь знает, возможно ли это? Или я застрял, повторяя создание название и внутри ФИО?
full_name = "test_instance_${n + 1}_v${var.infrastructure_version}"





Ваша последняя попытка верна. Вы не можете сделать это по-другому, и это работает:
full_name = "test_instance_${n + 1}_v${var.infrastructure_version}"
@kiabso, последний пример правильный, и это единственный способ. Если вам не нравится дублирование кода, то, возможно, terraform не для вас, и вам следует поискать другой инструмент для инфраструктуры в качестве кода.
Невозможно использовать имя, потому что имя не является локальной переменной, это пара ключ/значение в карте переменных, и карта не получает назначение до тех пор, пока она не будет сгенерирована циклом for.
@Marcin Я знаю, что это работает, хотя и не очень удобно. Но я прошу альтернативы. Например, функции, которые я обнаружил, не реализованы (пока?). Это была бы хорошая альтернатива
@victorm Я думаю, причина, по которой это не работает, заключается в том, что значение принадлежит карте, которая еще не построена. Но вы можете сделать locals { a = "foo", b = "${local.foo}_bar" }, поэтому не будет слишком надуманным, если что-то похожее на то, что я пытался сделать в своем исходном посте, сработает.
@kiabso Альтернативы нет. Я не уверен, что вы хотите сделать. Любой другой способ будет длиннее, если вы хотите ввести некоторые локальные списки.
Вместо того, чтобы выполнять интерполяцию переменных каждый раз, когда необходимо использовать значение, можно создать локальный модуль, который действует как функция. Где вы можете использовать локальные переменные и повторно использовать ранее созданные переменные.
Короткий пример ниже, он лучше подходит для более сложных и крупных приложений из-за больших накладных расходов.
main.tf: Из основного модуля я импортирую локальный модуль, который будет выполнять функции
module "instance_conf" {
source = "./modules"
count = var.size
index = count.index
infra = var.infrastructure_version
}
locals {
values = {for idx, val in module.instance_conf: idx => val}
}
Я отправляю индекс и инфра в модуль в качестве входных данных. Определения переменных в другом модуле должны совпадать с ними, здесь вы также можете предоставить описания, если это необходимо.
модули/func.tf:
variable "index" {
type = number
}
variable "infra" {
type = number
}
locals {
name = "instance_${var.index + 1}"
}
output "name" {
value = local.name
}
output "full_name" {
value = "test_${local.name}_v${var.infra}"
}
Чтобы получить желаемый вывод в основной модуль, вычислите значения либо в блоке локальных переменных, либо непосредственно в блоке вывода. При импорте этого модуля значения будут доступны в виде списка карт для каждого count.index в основном модуле. count = var.size
Список может выглядеть так:
[
{
name: "instance_1",
full_name: "test_instance_1_v1"
},
{
name: "instance_2",
full_name: "test_instance_2_v1"
},
...
]
Итак, чтобы использовать вывод модуля, как и в предыдущем случае, с for_each, я преобразовал список объектов карты в карту с индексом каждого объекта карты в качестве ключа для этого объекта.
locals {
values = {for idx, val in module.instance_conf: idx => val}
}
И теперь при использовании local.values это будет выглядеть так:
{
"1": {
name: "instance_1",
full_name: "test_instance_1_v1"
},
"2": {
name: "instance_2",
full_name: "test_instance_2_v1"
},
...
}
Теперь структура проекта выглядит так:
.
├── main.tf
├── modules
│ └── values_function.tf
Надеюсь, это поможет кому-то еще. Когда переменная интерполяция и воссоздание значения каждый раз, когда оно используется, не является приемлемым ответом. В основном из-за фактора ремонтопригодности.
Итак, вы говорите, что это невозможно. Последний пример не корректен, это всё-таки дублирование кода. Это выполняет цель в этом примере, который сильно упрощен.