Skip to content

Commit 6887cb6

Browse files
authored
Add support for Terraform v1.11 (#2258)
* Avoid crash due to map with `null` values Follow up of hashicorp/terraform#36611 * Update Terraform compatibility guide * Return error when the template's single interpolation results in null value Follow up of hashicorp/terraform#36658 * Bump patch version
1 parent b6b82ae commit 6887cb6

File tree

5 files changed

+68
-1
lines changed

5 files changed

+68
-1
lines changed

docs/user-guide/compatibility.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ TFLint interprets the [Terraform language](https://developer.hashicorp.com/terra
44

55
The parser supports Terraform v1.x syntax and semantics. The language compatibility on Terraform v1.x is defined by [Compatibility Promises](https://developer.hashicorp.com/terraform/language/v1-compatibility-promises). TFLint follows this promise. New features are only supported in newer TFLint versions, and bug and experimental features compatibility are not guaranteed.
66

7-
The latest supported version is Terraform v1.10.
7+
The latest supported version is Terraform v1.11.
88

99
## Input Variables
1010

terraform/lang/funcs/collection.go

+6
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,14 @@ var TransposeFunc = function.New(&function.Spec{
582582

583583
for it := inputMap.ElementIterator(); it.Next(); {
584584
inKey, inVal := it.Element()
585+
if inVal.IsNull() {
586+
return cty.MapValEmpty(cty.List(cty.String)), errors.New("input must not contain null list")
587+
}
585588
for iter := inVal.ElementIterator(); iter.Next(); {
586589
_, val := iter.Element()
590+
if val.IsNull() {
591+
return cty.MapValEmpty(cty.List(cty.String)), errors.New("input list must not contain null string")
592+
}
587593
if !val.Type().Equals(cty.String) {
588594
return cty.MapValEmpty(cty.List(cty.String)), errors.New("input must be a map of lists of strings")
589595
}

terraform/lang/funcs/collection_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,37 @@ func TestTranspose(t *testing.T) {
18331833
}).WithMarks(cty.NewValueMarks("beep", "boop", "bloop")),
18341834
false,
18351835
},
1836+
{
1837+
cty.NullVal(cty.Map(cty.List(cty.String))),
1838+
cty.NilVal,
1839+
true,
1840+
},
1841+
{
1842+
cty.MapVal(map[string]cty.Value{
1843+
"test": cty.NullVal(cty.List(cty.String)),
1844+
}),
1845+
cty.NilVal,
1846+
true,
1847+
},
1848+
{
1849+
cty.MapVal(map[string]cty.Value{
1850+
"test": cty.ListVal([]cty.Value{cty.NullVal(cty.String)}),
1851+
}),
1852+
cty.NilVal,
1853+
true,
1854+
},
1855+
{
1856+
cty.UnknownVal(cty.Map(cty.List(cty.String))),
1857+
cty.UnknownVal(cty.Map(cty.List(cty.String))).RefineNotNull(),
1858+
false,
1859+
},
1860+
{
1861+
cty.MapVal(map[string]cty.Value{
1862+
"test": cty.ListVal([]cty.Value{cty.UnknownVal(cty.String)}),
1863+
}),
1864+
cty.UnknownVal(cty.Map(cty.List(cty.String))).RefineNotNull(),
1865+
false,
1866+
},
18361867
}
18371868

18381869
for _, test := range tests {

terraform/lang/funcs/string.go

+8
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,14 @@ func makeRenderTemplateFunc(funcsCb func() (funcs map[string]function.Function,
380380
if diags.HasErrors() {
381381
return cty.DynamicVal, diags
382382
}
383+
if val.IsNull() {
384+
return cty.DynamicVal, &hcl.Diagnostic{
385+
Severity: hcl.DiagError,
386+
Summary: "Template result is null",
387+
Detail: "The result of the template is null, which is not a valid result for a templatestring call.",
388+
Subject: expr.Range().Ptr(),
389+
}
390+
}
383391
return val, nil
384392
}
385393
}

terraform/lang/funcs/string_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,28 @@ func TestTemplateString(t *testing.T) {
273273
want cty.Value
274274
wantErr string
275275
}{
276+
{ // a single string interpolation that evaluates to null should fail
277+
`template`,
278+
map[string]cty.Value{
279+
"template": cty.StringVal(`${test}`),
280+
},
281+
cty.ObjectVal(map[string]cty.Value{
282+
"test": cty.NullVal(cty.String),
283+
}),
284+
cty.NilVal,
285+
`<templatestring argument>:1,1-8: Template result is null; The result of the template is null, which is not a valid result for a templatestring call.`,
286+
},
287+
{ // a single string interpolation that evaluates to unknown should not fail
288+
`template`,
289+
map[string]cty.Value{
290+
"template": cty.StringVal(`${test}`),
291+
},
292+
cty.ObjectVal(map[string]cty.Value{
293+
"test": cty.UnknownVal(cty.String),
294+
}),
295+
cty.UnknownVal(cty.String).RefineNotNull(),
296+
``,
297+
},
276298
{
277299
`template`,
278300
map[string]cty.Value{

0 commit comments

Comments
 (0)