Search code examples
terraform

Lookup function not picking up the default value from the variable


We are facing an issue with the Lookup function. It’s not picking up the default value. I’ve defined the datastore default values in the variable.tf as a map and passed the temporary value from the tfvars.

I’ve got two keys defined in the TFvars. One of the keys doesn’t contain the datastore value; the lookup function should pick up the default value for that key, but it does not. Any suggestions?

Module code: (Adding only the relevant codes.)

module "vm_creation" {
  for_each        = var.vm
  source          = "Terraform-VMWare-Modules/vm/vsphere"
  version         = "3.8.0"
  dc              = var.dc_name[var.vsphere_datacentre]
  datastore       = lookup(each.value, "datastore_name", var.datastore_name[var.vsphere_datacentre])
  network         = each.value.network
  staticvmname    = "${var.vsphere_datacentre}-${each.value.vmname}"
  vmfolder        = var.folder_name
  vmgateway       = each.value.vmgateway
  vmrp            = var.pool_name[var.vsphere_datacentre]
  vmtemp          = var.vm_template[var.vsphere_datacentre]
...
}

Variable:

variable "vm" {
  type = map(object({
    network        = map(list(string))
    vmname         = string
    vmgateway      = string
    datastore_name = string
  }))
}

variable "datastore_name" {
  description = "Provide the datastore name"
  type        = map(string)
  default = {
    idev = "dev_nfs_hx"
    lon  = "lon_nfs_hx"
    rtp  = "rtp_nfs_hx"
  }
}

TFvars:

vsphere_datacentre = “idev”
domain_name        = “idev.com”
vsphere_env        = “idev”

vm = {
  coredns_vm_1 = {
    vmname = “coredns-1”,
    vmgateway = “10.1.15.1”
    network = {
      “vlan15” = [“10.1.15.101”],
    }
    datastore_name = “idev-011-raid1”
  },
  coredns_vm_2 = {
    vmname = “coredns-2”,
    vmgateway = “10.1.25.1”
    network = {
    “vlan25” = [“10.1.25.102”],
    }
  }
}

Error:

30: coredns_vm_2 = { │ 31: vmname = "coredns-2", │ 32: vmgateway = "10.15.25.1" │ 33: network = { │ 34: "vlan25" = ["10.15.25.102"], │ 35: } │ 38: │ 39: } │ 40: } │ │ The given value is not suitable for var.vm declared at variables.tf:121,1-14: element "coredns_vm_2": │ attribute "datastore_name" is required.


Solution

  • The lookup function is actually doing what it is supposed to do. The error comes from the fact the coredns_vm_2 key does not hold the datastore_name key, which is a required attribute as per your variable definition. What you could try is to define the datastore_name as an optional attribute, something like:

    variable "vm" {
      type = map(object({
        network        = map(list(string))
        vmname         = string
        vmgateway      = string
        datastore_name = optional(string, "")
      }))
    }
    

    Then, when calling the module, I would switch from using lookup to using ternary operator:

    datastore = each.value.datastore_name != "" ? each.value.datastore_name : var.datastore_name[var.vsphere_datacentre]