Skip to content

"panic: inconsistent list element types" when using optional object attributes across multiple modules #31844

@hanneshayashi

Description

@hanneshayashi

Terraform Version

Terraform v1.3.0
on darwin_arm64

Terraform Configuration Files

Root module:

module "my_module" {
  source = "./my_module"
  permissions = [
    {
      role = "foo"
      service_accounts = [
        "bar"
      ]
    },
    {
      role          = "roles/servicenetworking.networksAdmin"
      create_groups = true
    },
  ]
}

my_module:

variable "permissions" {
  type = list(object({
    role             = string
    create_groups    = optional(bool)
    service_accounts = optional(set(string))
    condition = optional(object({
      title       = string
      description = optional(string)
      expression  = string
    }))
  }))
  default = []
}

module "my_submodule" {
  source      = "./my_submodule"
  permissions = var.permissions
}

my_submodule:

variable "permissions" {
  type = list(object({
    role             = string
    create_groups    = optional(bool, false)
    service_accounts = optional(set(string), [])
    condition = optional(object({
      title       = string
      description = optional(string)
      expression  = string
    }))
  }))
  default = []
}

Debug Output

https://gist.github.com/hanneshayashi/fe9e91f2254f733a3cd3e57239bec856

Expected Behavior

Terraform doesn't crash.

Actual Behavior

Terraform crashes.

Steps to Reproduce

  1. terraform init
  2. terraform plan

Additional Context

It seems like Terraform 1.3.0 has a problem with optional attributes in lists of objects. We have multiple nested modules and we were using the experimental feature until now.
Since I can no longer use the default() function, I need to declare my variable in the "lowest" submodule like so:

variable "permissions" {
  type = list(object({
    role             = string
    create_groups    = optional(bool, false)     # Defaults here
    service_accounts = optional(set(string), []) # Defaults here
    condition = optional(object({
      title       = string
      description = optional(string)
      expression  = string
    }))
  }))
  default = []
}

Since I don't want to declare the defaults in all modules that use the submodule I declare the variable like so:

  type = list(object({
    role             = string
    create_groups    = optional(bool)        # No defaults here
    service_accounts = optional(set(string)) # No defaults here
    condition = optional(object({
      title       = string
      description = optional(string)
      expression  = string
    }))
  }))
  default = []}

When I then call the first module with two differently constructed objects Terraform crashes:

module "my_module" {
  source = "./my_module"
  permissions = [
    {
      role = "foo"
      service_accounts = [
        "bar"
      ]
    },
    {
      role          = "roles/servicenetworking.networksAdmin"
      create_groups = true
    },
  ]
}

Removing either of the objects prevents the crash.

References

No response

Metadata

Metadata

Assignees

Labels

bugconfigconfirmeda Terraform Core team member has reproduced this issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions