Вопрос или проблема
Короче говоря, имеется карта переменной длины, как эта
{
key1 = "val1",
key2 = "val2"
}
Я хочу превратить каждый из элементов в переменные для передачи в другой модуль, вот так:
var.key1 = "val1"
var.key2 = "val2"
Но без записи файла на диск. Единственный способ, который я смог найти – это записать каждый ключ в файл .tfvars.
Случай использования в том, что у меня есть модуль, как
variable "key1" {
type = string
}
variable "key2" {
type = string
default = ""
}
resource "someresource" "somename" {
setting1 = var.key1
setting2 = var.key2
}
А затем YAML файл
resource1:
settings:
setting1: value_of_s1
setting2: value_of_s2
который я хочу использовать для настройки someresource.somename
, загрузив настройки с помощью yamldecode
и передав их в модуль. Но потенциально есть сотни настроек, и не все из них будут определены в yaml файле, поэтому я хочу сделать это несколько динамически, не определяя каждую var.key1 = yamldecode(file())["settings"]["key1"]
(вы понимаете идею).
Если я правильно понимаю, вы хотите, чтобы некоторые настройки были определены в yaml файле, а другие предоставлялись во время выполнения. Вы можете объединить оба в новый словарь, прежде чем передать это в модуль, например:
$ cat settings.yml
resource1:
settings:
setting1: value_of_s1
setting2: value_of_s2
variable "key1" {
type = string
default = "foo"
}
variable "key3" {
type = string
default = "foobar"
}
locals {
variable_settings = {
"setting1" : var.key1,
"setting3" : var.key3,
}
yaml_settings = yamldecode(file("settings.yml"))["resource1"]["settings"]
settings = merge(local.yaml_settings, local.variable_settings, )
}
$ echo "local.settings" | terraform console
{
"setting1" = "foo"
"setting2" = "value_of_s2"
"setting3" = "foobar"
}
Как вы можете видеть, если переменная указана, то ее значение имеет приоритет над значением, определенным в yaml файле.
Ответ или решение
Чтобы преобразовать значения из map
в переменные в Terraform без необходимости записи в файл на диске, вы можете воспользоваться функцией merge
, которая позволяет объединить значения из разных источников. Ваша задача заключается в том, чтобы динамически принимать настройки из YAML-файла и смешивать их с переменными, определенными в вашем конфигурационном файле Terraform.
Вот шаги, которые помогут вам этого достичь:
- Определите переменные — сначала создайте переменные для значений, которые вы хотите использовать:
variable "key1" {
type = string
default = "foo" # Значение по умолчанию
}
variable "key3" {
type = string
default = "foobar" # Значение по умолчанию
}
- Загрузите настройки из YAML-файла — используйте функцию
yamldecode
, чтобы загрузить настройки из файла:
locals {
yaml_settings = yamldecode(file("settings.yml"))["resource1"]["settings"]
}
- Создайте общий объект настроек — используйте функцию
merge
, чтобы объединить значения из YAML-файла с вашими переменными:
locals {
variable_settings = {
"setting1" : var.key1,
"setting3" : var.key3,
}
settings = merge(local.yaml_settings, local.variable_settings)
}
- Используйте объединенные настройки в ресурсе — теперь вы можете использовать объединенные настройки в вашем ресурсе. Например:
resource "someresource" "somename" {
setting1 = local.settings["setting1"]
setting2 = lookup(local.settings, "setting2", "") # Значение по умолчанию пустой строке, если не указано
setting3 = lookup(local.settings, "setting3", "")
}
- Проверка полученных значений — вы можете проверить значения, которые были собраны, с помощью Terraform Console:
$ terraform console
> local.settings
{
"setting1" = "foo"
"setting2" = "value_of_s2"
"setting3" = "foobar"
}
Таким образом, если переменная определена в YAML-файле, то ее значение будет использоваться. Если переменной нет в YAML, то вы используете значение из переменной Terraform.
Этот подход позволяет вам динамически управлять переменными и значительно упрощает работу с большим количеством настроек, не требуя отдельных записей для каждой переменной.