azureterraformterraform-provider-azureterraform0.12+terraform-template-file

How to make a list parameter optional in terraform


I have the following configuration

abc:
  - vm_name: "abc"
    template:
      cate: Apple
      image: "ubuntu18"
    cpu_cores: 1
    memory: 1024
    cat:
      - red
      - geen
      - blue
  - vm_name: "xyz"
    template:
      cate: Orange
      image: "ubuntu18"
    cpu_cores: 1
    memory: 1024
    cat:
      - red
      - blue
      - yellow
      - black

and to group the vms into groups I use the code

locals {

  cfg_vars = yamldecode(file("test1.yaml"))
  list_color = flatten(local.config_vars["abc"][*]["cat"])

  
  inventory_map = merge([for color in local.list_color: {
    for vm in local.cfg_vars["abc"]:
      color => vm.vm_name... if contains(vm.cat, color)
      } 
  ]...)
}

The code works fine and I get the following list in local.inventory_map for above configuration.

{     
  "black" = [
    "xyz",  
  ]         
  "blue" = [
    "abc",  
    "xyz",  
  ]         
  "geen" = [  
    "abc",    
  ]        
  "red" = [   
    "abc",               
    "xyz",               
  ]           
  "yellow" = [           
    "xyz",               
  ]                      
}        


However, I want the parameter cat to be optional. But if I give a vm with no cat parameter, then nothing happens. I want it to work for the following configuration too

abc:
  - vm_name: "abc"
    template:
      cate: Apple
      image: "ubuntu18"
    cpu_cores: 1
    memory: 1024
    cat:
      - red
      - geen
      - blue
  - vm_name: "xyz"
    template:
      cate: Orange
      image: "ubuntu18"
    cpu_cores: 1
    memory: 1024
    cat:
      - red
      - blue
      - yellow
      - black
  - vm_name: "efg"
    template:
      cate: Orange
      image: "ubuntu18"
    cpu_cores: 1
    memory: 1024

As you can see, no cat parameter is defined in the third VM efg. In such case I want to get the same inventory file as above because the third vm is not using cat i.e.

{     
  "black" = [
    "xyz",  
  ]         
  "blue" = [
    "abc",  
    "xyz",  
  ]         
  "geen" = [  
    "abc",    
  ]        
  "red" = [   
    "abc",               
    "xyz",               
  ]           
  "yellow" = [           
    "xyz",               
  ]                      
} 


Solution

  • You can add lookup to the code to check for cat. If cat is not present, then you get empty list instead:

    locals {
      cfg_vars = yamldecode(file("test1.yaml"))
      list_color = distinct(flatten(
             [for vm in local.cfg_vars["abc"][*]: lookup(vm, "cat", [])]
          ))
      
      inventory_map = merge([for color in local.list_color: {
        for vm in local.cfg_vars["abc"]:
          color => vm.vm_name... if contains(lookup(vm, "cat", []), color)
          } 
      ]...)
    }