Skip to content

Commit

Permalink
Upgrade HCL to fix optional attr default crash
Browse files Browse the repository at this point in the history
Also add regression test coverage of the crash. This would occur when
objects with optional attributes had default values of different type
from the attribute type, and the objects were members of a collection.

For example:

list(object({
  a = optional(set(string), [])
}))

If this type constraint is applied to a variable value where one object
has a set(string) value for a, and the other object applies the empty
tuple default, Terraform would crash.
  • Loading branch information
alisdair committed Sep 23, 2022
1 parent 1e6f091 commit 10ae444
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -42,7 +42,7 @@ require (
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f
github.com/hashicorp/hcl/v2 v2.14.0
github.com/hashicorp/hcl/v2 v2.14.1
github.com/hashicorp/terraform-config-inspect v0.0.0-20210209133302-4fd17a0faac2
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -387,8 +387,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws=
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
github.com/hashicorp/hcl/v2 v2.14.0 h1:jX6+Q38Ly9zaAJlAjnFVyeNSNCKKW8D0wvyg7vij5Wc=
github.com/hashicorp/hcl/v2 v2.14.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
github.com/hashicorp/hcl/v2 v2.14.1 h1:x0BpjfZ+CYdbiz+8yZTQ+gdLO7IXvOut7Da+XJayx34=
github.com/hashicorp/hcl/v2 v2.14.1/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d h1:9ARUJJ1VVynB176G1HCwleORqCaXm/Vx0uUi0dL26I0=
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
Expand Down
64 changes: 64 additions & 0 deletions internal/terraform/context_apply_test.go
Expand Up @@ -12165,6 +12165,70 @@ output "out" {
}
}

func TestContext2Apply_moduleVariableOptionalAttributesDefaultChild(t *testing.T) {
m := testModuleInline(t, map[string]string{
"main.tf": `
variable "in" {
type = list(object({
a = optional(set(string))
}))
default = [
{ a = [ "foo" ] },
{ },
]
}
module "child" {
source = "./child"
in = var.in
}
output "out" {
value = module.child.out
}
`,
"child/main.tf": `
variable "in" {
type = list(object({
a = optional(set(string), [])
}))
default = []
}
output "out" {
value = var.in
}
`,
})

ctx := testContext2(t, &ContextOpts{})

// We don't specify a value for the variable here, relying on its defined
// default.
plan, diags := ctx.Plan(m, states.NewState(), SimplePlanOpts(plans.NormalMode, testInputValuesUnset(m.Module.Variables)))
if diags.HasErrors() {
t.Fatal(diags.ErrWithWarnings())
}

state, diags := ctx.Apply(plan, m)
if diags.HasErrors() {
t.Fatal(diags.ErrWithWarnings())
}

got := state.RootModule().OutputValues["out"].Value
want := cty.ListVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"a": cty.SetVal([]cty.Value{cty.StringVal("foo")}),
}),
cty.ObjectVal(map[string]cty.Value{
"a": cty.SetValEmpty(cty.String),
}),
})
if !want.RawEquals(got) {
t.Fatalf("wrong result\ngot: %#v\nwant: %#v", got, want)
}
}

func TestContext2Apply_provisionerSensitive(t *testing.T) {
m := testModule(t, "apply-provisioner-sensitive")
p := testProvider("aws")
Expand Down

0 comments on commit 10ae444

Please sign in to comment.