Skip to content

Terraform crash converting tuple to list of objects with optional attributes #32163

@Nuru

Description

@Nuru

Terraform Version

Terraform v1.3.4
on darwin_amd64

Terraform Configuration Files

Click to reveal

File bug.auto.tfvars

lifecycle_configuration_rules = [
  # Be sure to cover https://github.com/cloudposse/terraform-aws-s3-bucket/issues/137
  {
    abort_incomplete_multipart_upload_days = 1
    enabled                                = true
    # test no filter
    id = "nofilter"
    noncurrent_version_expiration = {
      newer_noncurrent_versions = 2
      noncurrent_days           = 30
    }
    transition = [
      {
        days          = 7
        storage_class = "GLACIER"
      },
    ]

  },
  {
    enabled = true
    expiration = {
      days                         = 93
      expired_object_delete_marker = false
    }
    # test filter without prefix
    filter_and = {
      object_size_greater_than = 256 * 1024
    }
    id = "big"
    noncurrent_version_expiration = {
      newer_noncurrent_versions = 2
      noncurrent_days           = 14
    }
    transition = [
      {
        days          = 90
        storage_class = "GLACIER"
      },
    ]
  }
]

File bug.tf

variable "lifecycle_configuration_rules" {
  type = list(object({
    enabled = optional(bool, true)
    id      = string # must be unique

    abort_incomplete_multipart_upload_days = optional(number)

    filter_and = optional(object({
      object_size_greater_than = optional(number) # integer >= 0
      object_size_less_than    = optional(number) # integer >= 1
      prefix                   = optional(string)
      tags                     = optional(map(string), {})
    }))
    expiration = optional(object({
      date                         = optional(string) # RFC3339 time format, GMT
      days                         = optional(number) # integer > 0
      expired_object_delete_marker = optional(bool)
    }))
    noncurrent_version_expiration = optional(object({
      newer_noncurrent_versions = optional(number) # integer > 0
      noncurrent_days           = optional(number) # integer >= 0
    }))
    transition = optional(list(object({
      date          = optional(string) # RFC3339 time format
      days          = optional(number) # integer > 0
      storage_class = string           # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
    })))
    noncurrent_version_transition = optional(list(object({
      newer_noncurrent_versions = optional(number) # integer >= 0
      noncurrent_days           = optional(number) # integer >= 0
      storage_class             = string           # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
    })))
  }))
  default     = []
  description = "A list of lifecycle V2 rules"
}

output "lifecycle_configuration_rules" {
  value = var.lifecycle_configuration_rules
}

Debug Output

Stack trace
!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

inconsistent list element types (cty.Object(map[string]cty.Type{"abort_incomplete_multipart_upload_days":cty.Number, "enabled":cty.Bool, "expiration":cty.Object(map[string]cty.Type{"date":cty.String, "days":cty.Number, "expired_object_delete_marker":cty.Bool}), "filter_and":cty.Object(map[string]cty.Type{"tags":cty.Map(cty.String)}), "id":cty.String, "noncurrent_version_expiration":cty.Object(map[string]cty.Type{"newer_noncurrent_versions":cty.Number, "noncurrent_days":cty.Number}), "noncurrent_version_transition":cty.List(cty.Object(map[string]cty.Type{"newer_noncurrent_versions":cty.Number, "noncurrent_days":cty.Number, "storage_class":cty.String})), "transition":cty.List(cty.Object(map[string]cty.Type{"date":cty.String, "days":cty.Number, "storage_class":cty.String}))}) then cty.Object(map[string]cty.Type{"abort_incomplete_multipart_upload_days":cty.Number, "enabled":cty.Bool, "expiration":cty.Object(map[string]cty.Type{"date":cty.String, "days":cty.Number, "expired_object_delete_marker":cty.Bool}), "filter_and":cty.Object(map[string]cty.Type{"object_size_greater_than":cty.Number, "object_size_less_than":cty.Number, "prefix":cty.String, "tags":cty.Map(cty.String)}), "id":cty.String, "noncurrent_version_expiration":cty.Object(map[string]cty.Type{"newer_noncurrent_versions":cty.Number, "noncurrent_days":cty.Number}), "noncurrent_version_transition":cty.List(cty.Object(map[string]cty.Type{"newer_noncurrent_versions":cty.Number, "noncurrent_days":cty.Number, "storage_class":cty.String})), "transition":cty.List(cty.Object(map[string]cty.Type{"date":cty.String, "days":cty.Number, "storage_class":cty.String}))}))
goroutine 12 [running]:
runtime/debug.Stack()
	/usr/local/go/src/runtime/debug/stack.go:24 +0x65
runtime/debug.PrintStack()
	/usr/local/go/src/runtime/debug/stack.go:16 +0x19
github.com/hashicorp/terraform/internal/logging.PanicHandler()
	/Users/distiller/project/project/internal/logging/panic.go:55 +0x153
panic({0x2de7d80, 0xc000ca1670})
	/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/zclconf/go-cty/cty.ListVal({0xc00063fa80, 0x2, 0x1?})
	/Users/distiller/go/pkg/mod/github.com/zclconf/go-cty@v1.12.0/cty/value_init.go:166 +0x42e
github.com/zclconf/go-cty/cty.transform({0x0?, 0x0, 0x0}, {{{0x37727f0?, 0xc000ca0bf0?}}, {0x2cf61a0?, 0xc0003dd128?}}, {0x3759b60, 0xc000014dd8})
	/Users/distiller/go/pkg/mod/github.com/zclconf/go-cty@v1.12.0/cty/walk.go:175 +0xf4a
github.com/zclconf/go-cty/cty.TransformWithTransformer(...)
	/Users/distiller/go/pkg/mod/github.com/zclconf/go-cty@v1.12.0/cty/walk.go:130
github.com/hashicorp/hcl/v2/ext/typeexpr.(*Defaults).Apply(0xc000053e20?, {{{0x37727f0?, 0xc000ca0bf0?}}, {0x2cf61a0?, 0xc0003dd128?}})
	/Users/distiller/go/pkg/mod/github.com/hashicorp/hcl/v2@v2.14.1/ext/typeexpr/defaults.go:38 +0xa7
github.com/hashicorp/terraform/internal/terraform.prepareFinalInputVariableValue({{0x0, 0x0, 0x0}, {{}, {0xc00039e920, 0x1d}}}, 0xc000232a80, 0xc0003b5ee0)
	/Users/distiller/project/project/internal/terraform/eval_variable.go:140 +0xaed
github.com/hashicorp/terraform/internal/terraform.(*NodeRootVariable).Execute(0xc00099c280, {0x3788db8, 0xc0005a8460}, 0x0?)
	/Users/distiller/project/project/internal/terraform/node_root_variable.go:82 +0x214
github.com/hashicorp/terraform/internal/terraform.(*ContextGraphWalker).Execute(0xc000ca4000, {0x3788db8, 0xc0005a8460}, {0xcb8be38, 0xc00099c280})
	/Users/distiller/project/project/internal/terraform/graph_walk_context.go:136 +0xc2
github.com/hashicorp/terraform/internal/terraform.(*Graph).walk.func1({0x2f57800, 0xc00099c280})
	/Users/distiller/project/project/internal/terraform/graph.go:74 +0x2f0
github.com/hashicorp/terraform/internal/dag.(*Walker).walkVertex(0xc00097c840, {0x2f57800, 0xc00099c280}, 0xc00063f640)
	/Users/distiller/project/project/internal/dag/walk.go:381 +0x2f6
created by github.com/hashicorp/terraform/internal/dag.(*Walker).Update
	/Users/distiller/project/project/internal/dag/walk.go:304 +0xf65

Expected Behavior

Output should have been normalized input

Actual Behavior

Terraform crash

Steps to Reproduce

  1. terraform plan

Additional Context

Issue created at the request of @liamcervante with minimal reproduction requiring no providers.

References

Metadata

Metadata

Assignees

Labels

bugconfirmeda Terraform Core team member has reproduced this issueduplicateissue closed because another issue already tracks this problemexplaineda Terraform Core team member has described the root cause of this issue in code

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions