The given value is not suitable (for a variable in a variables.tf), list of object required

I’m trying to pass of list of Azure virtual machines to create by way of a variable to the root main.tf. However, I keep getting this error. I even consulted ChatGPT 4 and it produced the exact same code.

Here is the error:

│ The given value is not suitable for var.virtual_machines declared at variables.tf:44,1-28: element 0: attribute
│ "source_image_reference": list of object required.

Here is the definition of the variable in the variables.tf used in the root main.tf:

variable "virtual_machines" {
    description = "A list of virtual machines to create."
    type = list(object({
        name = string        
        resource_group_name = string
        location            = string
        size                = string
        admin_username      = string
        admin_password      = string
        availability_set    = string
        subnet_name         = string

        os_disk = list(object({
            caching           = string
            storage_account_type = string
            disk_size_gb      = number 
        }))
        
        source_image_reference = list(object({
            publisher = string
            offer     = string
            sku       = string
            version   = string   
        }))
    }))

    default = []
}

Here is the value of the variable in the terraform.auto.tfvars file:

virtual_machines = [
  {
    name                = "vm-dc1-eastus-001"
    resource_group_name = "rg-servers-eastus-001"
    location            = "eastus"
    size                = "Standard_DS1_v2"
    admin_username      = ""
    admin_password      = ""
    availability_set    = "avb-dcs-eastus-001"
    subnet_name         = "snet-dcs-eastus-001"

    os_disk = {
      caching           = "ReadWrite"        
      storage_account_type = "Standard_LRS"
      disk_size_gb      = 127
    }

    source_image_reference = {
      publisher = "MicrosoftWindowsServer"
      offer     = "WindowsServer"
      sku       = "2019-Datacenter" # Server2022 to be added
      version   = "latest"
    }
  }
]

I’m not sure what exactly is wrong, any help would be greatly appreciated!

Hi @farslayer9. Your type specifies source_image_reference as a list(object(…)), but your variable value has an object(…) instead.

In your value, you currently have:

source_image_reference = {
  publisher = "MicrosoftWindowsServer"
  offer     = "WindowsServer"
  sku       = "2019-Datacenter" # Server2022 to be added
  version   = "latest"
}

If you’re sure it makes sense to have a list of source images, try changing this to:

 source_image_reference = [
  {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter" # Server2022 to be added
    version   = "latest"
  },
]

If instead there should only be a single image reference, instead change the type to just object(…).

It actually makes more sense to just have a single block with one item, there won’t be more than a single OS disk or a single_image_reference. But I do need to specify multiple VMs both in the variables file and also the variables.tf needs to accommodate this. Also, why does it not error on the os_disk? I tried to change it to os_disk = object(…) but I get a syntax error in VSCode.

This is in the terraform.auto.tfvars file now:

source_image_reference = object(
publisher = “MicrosoftWindowsServer”
offer = “WindowsServer”
sku = “2019-Datacenter” # Server2022 to be added
version = “latest”
)

It errors at "publisher = “MicrosoftWindowsServer”, and it’s now not happy with the os_disk section. I need to group these logically, and eventually I will have a list of objects for data disks within here.
Thanks!

The goal is that in the virtual_machines module, I can access the values as var.virtualmachine.name, var.virtualmachine.source_image_reference.offer, if that helps.

Hi @farslayer9,

To declare that os_disk expects only a single object, you can write its declaration like this:

        os_disk = object({
            caching              = string
            storage_account_type = string
            disk_size_gb         = number 
        })

Similarly for source_image_reference:

        source_image_reference = object({
            publisher = string
            offer     = string
            sku       = string
            version   = string   
        })

You should make these changes in the variables.tf file.

These attribute declarations both state that each element of var.virtual_machines must have exactly one os_disk object and exactly one source_image_reference object, which should therefore match the values you wrote in the terraform.auto.tfvars file.