In short, given a map with an arbitrary number of elements, for example:
{
key1 = "val1",
key2 = "val2"
}
I want to turn each of the elements into variables (convert a map to vars or locals):
var.key1 = "val1"
var.key2 = "val2"
But without writing a file to disk. The only way I could find was to write each key out to a .tfvars file.
The use case is that I have a module (say “modules/myresource”) that looks like
variable "setting1" {
type = string
}
variable "setting2" {
type = string
default = ""
}
resource "someresource" "somename" {
setting1 = var.setting1
setting2 = var.setting2
}
And then a YAML file (resource1.yaml)
resource1:
settings:
setting1: value_of_s1
setting2: value_of_s2
which I want to use to configure someresource.somename
by loading the settings with yamldecode
and passing them to the module. But there are potentially hundreds of settings and not all of them would be defined in the yaml file, so I want to do this without having to define each setting in my module {}
block.
So, instead of:
locals {
resource_settings = yamldecode(file("resource1.yaml"))["settings"]
}
module "myresource1" {
source = "./modules/myresource"
setting1 = local.resource_settings["setting1"]
setting2 = local.resource_settings["setting2"]
}
I want something like:
locals {
resource_settings = yamldecode(file("resource1.yaml"))["settings"]
}
module "myresource1" {
source = "./modules/myresource"
for_each = local.resource_settings
{each.key} = each.value
}
That’s obviously not going to work, but hopefully it clarifies what I’m after a bit.
3
If I understand correctly, you’re looking to have some settings defined in the yaml file and others provided at run time. You can merge the two into a new dict before passing that to a module, e.g.:
$ 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"
}
so as you can see if the variable is specified then its value takes precedence over that defined in the yaml file.
1