Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Terraform crash with nested optional default values #32152

Closed
danischm opened this issue Nov 3, 2022 · 8 comments · Fixed by #32178
Closed

Terraform crash with nested optional default values #32152

danischm opened this issue Nov 3, 2022 · 8 comments · Fixed by #32178
Assignees
Labels
bug confirmed a Terraform Core team member has reproduced this issue explained a Terraform Core team member has described the root cause of this issue in code v1.3 Issues (primarily bugs) reported against v1.3 releases

Comments

@danischm
Copy link

danischm commented Nov 3, 2022

Terraform Version

1.3.4

Terraform Configuration Files

https://github.com/danischm/tf-nested-optional-crash

Debug Output

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

Terraform crashed! This is always indicative of a bug within Terraform.
Please report the crash with Terraform1 so that we can fix this.

When reporting bugs, please include your terraform version, the stack trace
shown below, and any additional information which may help replicate the issue.

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

inconsistent list element types (cty.Object(map[string]cty.Type{"optional_list":cty.List(cty.Object(map[string]cty.Type{"optional_string":cty.String, "string":cty.String})), "string":cty.String}) then cty.Object(map[string]cty.Type{"optional_list":cty.List(cty.ObjectWithOptionalAttrs(map[string]cty.Type{"optional_string":cty.String, "string":cty.String}, []string{"optional_string"})), "string":cty.String}))
goroutine 16 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x64
runtime/debug.PrintStack()
/usr/local/go/src/runtime/debug/stack.go:16 +0x1c
github.com/hashicorp/terraform/internal/logging.PanicHandler()
/Users/distiller/project/project/internal/logging/panic.go:55 +0x170
panic({0x104479500, 0x1400021e0c0})
/usr/local/go/src/runtime/panic.go:884 +0x204
github.com/zclconf/go-cty/cty.ListVal({0x1400078e3c0, 0x2, 0x1?})
/Users/distiller/go/pkg/mod/github.com/zclconf/go-cty@v1.12.0/cty/value_init.go:166 +0x454
github.com/zclconf/go-cty/cty.transform({0x0?, 0x0, 0x0}, {{{0x10487e610?, 0x1400033c7a0?}}, {0x104387a20?, 0x140007ccff0?}}, {0x104865a80, 0x140007c8318})
/Users/distiller/go/pkg/mod/github.com/zclconf/go-cty@v1.12.0/cty/walk.go:175 +0xb9c
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(0x14000576a60?, {{{0x10487e610?, 0x1400033c7a0?}}, {0x104387a20?, 0x140007ccff0?}})
/Users/distiller/go/pkg/mod/github.com/hashicorp/hcl/v2@v2.14.1/ext/typeexpr/defaults.go:38 +0x9c
github.com/hashicorp/terraform/internal/terraform.prepareFinalInputVariableValue({{0x0, 0x0, 0x0}, {{}, {0x14000264178, 0x4}}}, 0x14000431030, 0x140005c5d40)
/Users/distiller/project/project/internal/terraform/eval_variable.go:140 +0x854
github.com/hashicorp/terraform/internal/terraform.(*NodeRootVariable).Execute(0x140008627c0, {0x104892a38, 0x140002b0700}, 0xc0?)
/Users/distiller/project/project/internal/terraform/node_root_variable.go:82 +0x168
github.com/hashicorp/terraform/internal/terraform.(*ContextGraphWalker).Execute(0x14000860000, {0x104892a38, 0x140002b0700}, {0x12dbe7d38, 0x140008627c0})
/Users/distiller/project/project/internal/terraform/graph_walk_context.go:136 +0xa8
github.com/hashicorp/terraform/internal/terraform.(*Graph).walk.func1({0x1045e8f20, 0x140008627c0})
/Users/distiller/project/project/internal/terraform/graph.go:74 +0x208
github.com/hashicorp/terraform/internal/dag.(*Walker).walkVertex(0x1400085d980, {0x1045e8f20, 0x140008627c0}, 0x1400078e180)
/Users/distiller/project/project/internal/dag/walk.go:381 +0x2e0
created by github.com/hashicorp/terraform/internal/dag.(*Walker).Update
/Users/distiller/project/project/internal/dag/walk.go:304 +0xbf0

Expected Behavior

no crash

Actual Behavior

crash

Steps to Reproduce

  1. terraform apply

Additional Context

Removing the default value [] in line 7 main.tf fixes the crash. A git bisect revealed the following 'bad' commit: 6521355

References

No response

@danischm danischm added bug new new issue not yet triaged labels Nov 3, 2022
@liamcervante
Copy link
Member

Hi @danischm, thanks for the report and for the easy to reproduce config files.

I can confirm that I can reproduce this, we'll take a look to see about potential fixes and the root cause.

@liamcervante liamcervante added confirmed a Terraform Core team member has reproduced this issue and removed new new issue not yet triaged labels Nov 3, 2022
@liamcervante
Copy link
Member

The root cause for this is within the go-cty downstream dependency via the hcl dependency. HCL initially reads in the default value for the list as a tuple, and then converts it into a list using the go-cty conversion functions.

Historically the conversion functions have not dealt consistently with optional attributes, and the tuple to list function is missing some recent fixes which result in the default value for the "def" object and the provided value for the "abc" object having different optional metadata. Then we see the crash when HCL attempts to combine these objects into a list have they have different types.

We'll need to do another pass over go-cty to fix the conversion functions, and then update the dependency in HCL, and then update Terraform with new versions of HCL and go-cty.

@liamcervante liamcervante added the explained a Terraform Core team member has described the root cause of this issue in code label Nov 3, 2022
@claudioscalzo
Copy link

I can confirm we're experiencing the same with a similar configuration:

variable "domains" {
  type = map(object({
    rules = map(object({
      backend = optional(string)
      url_redirect = optional(object({
        destination   = string
        preserve_path = optional(bool, true)
      }))
    }))
  }))
}

Output:

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

inconsistent map element types (
cty.Object(map[string]cty.Type{"rules":cty.Map(cty.Object(map[string]cty.Type{"backend":cty.String, "url_redirect":cty.Object(map[string]cty.Type{"preserve_path":cty.Bool})}))})
then
cty.Object(map[string]cty.Type{"rules":cty.Map(cty.Object(map[string]cty.Type{"backend":cty.String, "url_redirect":cty.Object(map[string]cty.Type{"destination":cty.String, "preserve_path":cty.Bool})}))})
)

@liamcervante
Copy link
Member

Hi @claudioscalzo - can you share some more information about how you are using that variable? Or what value you are giving it that causes the crash?

I can't reproduce your crash just with that variable, and I'd like to check it's the same root cause and that my fix works for this locally as well.

Thanks!

@claudioscalzo
Copy link

claudioscalzo commented Nov 3, 2022

Hi @liamcervante - Sure! Here's a full configuration (working on 1.3.3) which triggers the crash on version 1.3.4.

main.tf:

module "fake_module" {
  source = "./fake-module"

  domains = {
    "domain-1" = {
      rules = {
        "/" = {
          backend = "backend-a"
        }
      }
    }

    "domain-2" = {
      rules = {
        "/" = {
          url_redirect = {
            destination   = "https://redirect.fake.domain.com/alertmanager"
            preserve_path = false
          }
        }
      }
    }
  }
}

fake-module/variables.tf:

variable "domains" {
  type = map(object({
    rules = map(object({
      backend = optional(string)
      url_redirect = optional(object({
        destination   = string
        preserve_path = optional(bool, true)
      }))
    }))
  }))
}

@liamcervante
Copy link
Member

Hi @claudioscalzo, thanks for that. I've investigated and I think it has a different root cause to this issue. I've filed a new issue linked above, and included a potential workaround for you in the comments there.

I haven't been able to find a workaround for this issue yet.

@liamcervante liamcervante added the v1.3 Issues (primarily bugs) reported against v1.3 releases label Nov 3, 2022
@claudioscalzo
Copy link

Hi @liamcervante - Thanks for the investigation and the workarounds you proposed. Currently, we decided to pin the 1.3.3 version as this bug has a big impact on many internal modules we use, and both workarounds would cause a non-negligible change in the modules logic/interface.

Hoping for a fix, thanks for the quick response to the issue!

@github-actions
Copy link
Contributor

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 11, 2022
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
bug confirmed a Terraform Core team member has reproduced this issue explained a Terraform Core team member has described the root cause of this issue in code v1.3 Issues (primarily bugs) reported against v1.3 releases
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants