[SOLVED] element "XXX": attribute "XXX": element "XXX": object required

Hi there!

Since few days I had this error message when running terraform plan:

[...]
element "XXX": attribute "XXX": element "XXX": object required.

I dug around and fell on this thread: The given value is not suitable for module.

It took me a moment to understand great explanations of master @apparentlymart , but at the end, I make it!

For those who wants an illustration to understand and fix this object required issue:

Here is a working code:

virtual_networks = {
  test = {
    division  = "test",
    prefix    = ["10.2.71.0/24"],
    int_id = "c2",
    subnets = {
      test = {
        prefix             = ["10.2.71.0/25"],
        env                = "test",
        application_name   = "xxx",
        application_layout = "development",
        route_table        = "standard",
        int_id = "c2"
      },
      test_pe = {
        prefix             = ["10.2.71.128/25"],
        env                = "test",
        application_name   = "xxx",
        application_layout = "developmentpe",
        route_table        = "standard",
        int_id = "c2"
      }
    }
  }
}

Here is the corresponding tfvars:

variable "virtual_networks" {
  description = "Map of virtual networks to create with their subnets"
  type = map(object({
    division  = string,
    prefix    = list(string),
    int_id = optional(string),
    subnets = map(object({
      env                = string,
      application_name   = string,
      application_layout = string,
      int_id = optional(string),
      prefix             = list(string)
      route_table        = string
    }))
    }
    )
  )
}

What is important here is to notice **that** :point_down:t2::

[...]
  subnets = {
      **test = {**
        prefix             = ["10.2.71.0/25"]
        [...]
      },
      **test_pe = {**
        prefix             = ["10.2.71.128/25"]
        [...]
     }
}

Subnet is effectively referencing 2 maps: test and test_pe.

Now, here is a NOT working code:

test_compute_clusters = {
  mlcc_test = {
    index = "1",
    division         = "devpe",
    identity_type = "SystemAssigned",
    priority = "LowPriority",
    node_public_ip_enabled = false,
    virtual_machine_size = "STANDARD_DS4_V2",
    test_workspace_key = "test",
    subnet_key = "snet-001",
    scale_settings = {
       max_node_count = 1,
       min_node_count = 0,
       scale_down_nodes_after_idle_duration = "PT3M"
    }
}

With this tfvars:

variable "test_compute_clusters " {
  description = "Machine learning compute cluster definition"
  type = map(object({
    index                                               = optional(string),
    context                                             = string,
    identity_type                                       = string,
    priority                                            = string,
    node_public_ip_enabled                              = optional(bool, false),
    virtual_machine_size                                = string,
    test_workspace_key                                   = string,
    subnet_key                                          = string,
    scale_settings = map(object({
      max_node_count                       = number,
      min_node_count                       = number,
      scale_down_nodes_after_idle_duration = string
    }))
  }))
}

What is important here is to notice ** that ** :point_down:t2::

subnet_key = "snet-001",
    scale_settings = {
       **max_node_count = 1,**
       **min_node_count  = 0,**
       **scale_down_nodes_after_idle_duration = "PT3M"**
    }))

scale_settings is NOT REFERENCING a map! but objects only!!!

If I really want scale_settings being a map and avoid the object required message, I should had written this:

subnet_key = "snet-001",
    scale_settings = {
       settings_1 = {              #<============ HERE IS MY MISTAKE
         max_node_count = 1,
         min_node_count  = 0,
         scale_down_nodes_after_idle_duration = "PT3M"
    }}))

and not this

subnet_key = "snet-001",
    scale_settings = {
         max_node_count = 1,  #<===== SEE HERE? NO MAP BEFORE `max_node_count`!
         min_node_count = 0,
         scale_down_nodes_after_idle_duration = "PT3M"
    }}))

So, Terraform was correct, what I needed here was an object and not a map of object!

I hope this post will be useful to anybody & Thanks to @apparentlymart !

Have a nice day!