I'm trying to create a map in locals where a key is created dynamically based on the value of another variable, and can't find a functional way of doing this in Terraform.
The map contains subnet configuration parameters, in the format:
  <subnet-name> = {
    subnet_id = <subnet-id> 
    nsg_id    = <nsg-id>
    rtbl_id   = <rtbl-id>
  }
And I'm creating it like this:
  snet_mappings = {
    for key in keys(module.subnet.snet-ids) : key => { 
      snet_id = module.subnet.snet-ids[key], 
      nsg_id  = module.nsg.nsg-ids[var.snet_config[key]["nsg"]], 
      rtbl_id = module.route-table.rtbl-ids[var.snet_config[key]["route_table"]]
    }
  }
With the following variable acting as the lookup for the NSG/Route Table to add from the ones created:
snet_config = {
    "testsub" = {
        "address_space" = ["10.10.0.0/24"]
        "nsg"           = "nsg-001"
        "route_table"   = "rtbl-001"
    }
}
This works perfectly so long as I define an NSG and a Route Table every time in the snet_config map.  It doesn't work for a case like this however where I don't want the Route Table to be set, so I leave it blank:
snet_config = {
    "testsub" = {
        "address_space" = ["10.10.0.0/24"]
        "nsg"           = "nsg-001"
        "route_table"   = ""
    }
}
This is because it tries to lookup the Route Table ID with an empty string, which therefore fails as it doesn't match a key in the route-table.rtbl-ids map.  In the instance where route table isn't set, I actually want my map to look like this:
  <subnet-name> = {
    subnet_id = <subnet-id> 
    nsg_id    = <nsg-id>
  }
i.e. the rtbl_id key isn't set at all.  Is it possible to conditionally create keys?  I've tried playing around with Terraform conditionals but can't find a working solution.
 
                        
If you are optionally specifying the key, then you can use the
merge,keys, andcontainsfunctions with a ternary to accomplish this:alternatively with
can:The null coealescing functionality with
coalescecannot be used here as it pertains to an optional key.If instead you specify an empty string for
route_tablewhen unused and always specify it as a key, then you would conditional off the length of the string:In all three situations the
mergefunction ensure the extra key-value pair only exists in the returned map based on the conditional, and therefore this satisfies the desired functionality.