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.
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]