Search code examples
terraformyaml

Iterating over multi-level yaml values in terraform


I'm trying to shorten my terraform code for deploying azure vnets by iterating over values I provide in a yaml file. I want to write one .tf file with the code for the vnets, the subnets, the NSGs, etc. but I'm struggling to get the locals block right to correctly iterate through my yaml file (see below)

vnets:
  - name: adds
    location: eastus
    address_space: ["10.1.0.0/24"]
    subnets:
      - name: adds
        address_prefix: "10.1.0.0/27"
  - name: dns
    location: eastus
    address_space: ["10.1.53.0/24"]
    subnets:
      - name: dns-inbound
        address_prefix: "10.1.53.0/28"
      - name: dns-outbound
        address_prefix: "10.1.53.16/28"

Any help on how I should right my locals block would be appreciated!


Solution

  • This code will transform your yaml file into local map:

    locals {
      vnets = yamldecode(file("./test.yaml"))
    
      vnets_map = {
        for vnet in local.vnets.vnets : 
          vnet.name => {
            address_space = vnet.address_space
            location = vnet.location
            subnets = {
              for subnet in vnet.subnets :
                subnet.name => subnet.address_prefix
            }
          }
      }
    }
    
    output "example-output-dns-inbound-subnet" {
      value = local.vnets_map.dns.subnets.dns-inbound
    }
    

    I took the liberty of changing lists to maps - it is better to navigate in terraform. Entire vnets_map object looks like this:

    {
      "adds" = {
        "address_space" = [
          "10.1.0.0/24",
        ]
        "location" = "eastus"
        "subnets" = {
          "adds" = "10.1.0.0/27"
        }
      }
      "dns" = {
        "address_space" = [
          "10.1.53.0/24",
        ]
        "location" = "eastus"
        "subnets" = {
          "dns-inbound" = "10.1.53.0/28"
          "dns-outbound" = "10.1.53.16/28"
        }
      }
    }