I have a yaml file (also used in a azure devops pipeline so needs to be in this format) which contains some settings I'd like to directly access from my terraform module.
The file looks something like:
variables:
- name: tenantsList
value: tenanta,tenantb
- name: unitName
value: canary
I'd like to have a module like this to access the settings but I can't see how to get to the bottom level:
locals {
settings = yamldecode(file("../settings.yml"))
}
module "infra" {
source = "../../../infra/terraform/"
unitname = local.settings.variables.unitName
}
But the terraform plan
errors with this:
Error: Unsupported attribute
on canary.tf line 16, in module "infra":
16: unitname = local.settings.variables.unitName
|----------------
| local.settings.variables is tuple with 2 elements
This value does not have any attributes.
It seems like the main reason this is difficult is because this YAML file is representing what is logically a single map but is physically represented as a YAML list of maps.
When reading data from a separate file like this, I like to write an explicit expression to normalize it and optionally transform it for more convenient use in the rest of the Terraform module. In this case, it seems like having
variables
as a map would be the most useful representation as a Terraform value, so we can write a transformation expression like this:The above uses a
for
expression to project the list of maps into a single map using thename
values as the keys.With the list of maps converted to a single map, you can then access it the way you originally tried:
If you were to output the transformed value of
local.settings
as YAML, it would look something like this, which is why accessing the map elements directly is now possible:This will work only if all of the
name
strings in your input are unique, because otherwise there would not be a unique map key for each element.(Writing a normalization expression like this also doubles as some implicit validation for the shape of that YAML file: if
variables
were not a list or if the values were not all of the same type then Terraform would raise a type error evaluating that expression. Even if no transformation is required, I like to write out this sort of expression anyway because it serves as some documentation for what shape the YAML file is expected to have, rather than having to study all of the references to it throughout the rest of the configuration.)