'Using terraform yamldecode to access multi level element

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.


Solution 1:[1]

Try out my self implemented module. You can open multiple YAML files in one run with it. Place this somewhere, where you like to access one or multiple YAML files.

Usage

module "yaml" {
  source  = "levmel/yamldecode/multiple"
  version = "0.0.1"
  filepaths = ["routes/nsg_rules.yaml.", "network/private_endpoints/*.yaml"]
}

You should change the filepaths with the relative paths of your YAML files. If you like to select all YAML files in a folder, then you should do it with a "*" before the ".yaml" format. (see above)

Pattern to access entries in a YAML file:

module.yaml.files.[name_of_your_file_without_format].entry


Pattern to write relative paths:

For all YAML files in a folder structure use this "folder/../*.yaml". For specific YAML file in a folder structure use this "folder/../name_of_yaml.yaml"

Example

routes/nsg_rules.yaml

aks:
  rdp:
    name: rdp
    priority: 80
    direction: Inbound
    access: Allow
    protocol: Tcp
    source_port_range: "*"
    destination_port_range: 3389
    source_address_prefix: VirtualNetwork
    destination_address_prefix: "*"
  ssh:
    name: ssh
    priority: 70
    direction: Inbound
    access: Allow
    protocol: Tcp
    source_port_range: "*"
    destination_port_range: 24
    source_address_prefix: VirtualNetwork
    destination_address_prefix: "*"

Access entry in nsg_rules.yaml:

module "yaml" {
  source  = "levmel/yamldecode/multiple"
  version = "0.0.1"
  filepaths = ["routes/nsg_rules.yaml."]
}

output "test" {
  value = module.yaml.files.nsg_rules.aks.rdp.name
}

Output is: "test" = "rdp"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Levon Melikbekjan