lang/funcs: templatefile requires valid variable names
Previously the templatefile function would permit any arbitrary string as a variable name, but due to the HCL template syntax it would be impossible to refer to one that isn't a valid HCL identifier without causing an HCL syntax error. The HCL syntax errors are correct, but don't really point to the root cause of the problem. Instead, we'll pre-verify that the variable names are valid before we even try to render the template, and given a specialized error message that refers to the vars argument expression as the problematic part, which will hopefully make the resolution path clearer for a user encountering this situation. The syntax error still remains for situations where all of the variable names are correct but e.g. the user made a typo referring to one, which makes sense because in that case the problem _is_ inside the template.
This commit is contained in:
parent
ec9f950b3f
commit
67d95b97ce
|
@ -100,6 +100,20 @@ func MakeTemplateFileFunc(baseDir string, funcsCb func() map[string]function.Fun
|
||||||
Variables: varsVal.AsValueMap(),
|
Variables: varsVal.AsValueMap(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We require all of the variables to be valid HCL identifiers, because
|
||||||
|
// otherwise there would be no way to refer to them in the template
|
||||||
|
// anyway. Rejecting this here gives better feedback to the user
|
||||||
|
// than a syntax error somewhere in the template itself.
|
||||||
|
for n := range ctx.Variables {
|
||||||
|
if !hclsyntax.ValidIdentifier(n) {
|
||||||
|
// This error message intentionally doesn't describe _all_ of
|
||||||
|
// the different permutations that are technically valid as an
|
||||||
|
// HCL identifier, but rather focuses on what we might
|
||||||
|
// consider to be an "idiomatic" variable name.
|
||||||
|
return cty.DynamicVal, function.NewArgErrorf(1, "invalid template variable name %q: must start with a letter, followed by zero or more letters, digits, and underscores", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We'll pre-check references in the template here so we can give a
|
// We'll pre-check references in the template here so we can give a
|
||||||
// more specialized error message than HCL would by default, so it's
|
// more specialized error message than HCL would by default, so it's
|
||||||
// clearer that this problem is coming from a templatefile call.
|
// clearer that this problem is coming from a templatefile call.
|
||||||
|
|
|
@ -86,6 +86,14 @@ func TestTemplateFile(t *testing.T) {
|
||||||
cty.StringVal("Hello, Jodie!"),
|
cty.StringVal("Hello, Jodie!"),
|
||||||
``,
|
``,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
cty.StringVal("testdata/hello.tmpl"),
|
||||||
|
cty.MapVal(map[string]cty.Value{
|
||||||
|
"name!": cty.StringVal("Jodie"),
|
||||||
|
}),
|
||||||
|
cty.NilVal,
|
||||||
|
`invalid template variable name "name!": must start with a letter, followed by zero or more letters, digits, and underscores`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
cty.StringVal("testdata/hello.tmpl"),
|
cty.StringVal("testdata/hello.tmpl"),
|
||||||
cty.ObjectVal(map[string]cty.Value{
|
cty.ObjectVal(map[string]cty.Value{
|
||||||
|
|
|
@ -29,7 +29,9 @@ into a separate file for readability.
|
||||||
The "vars" argument must be a map. Within the template file, each of the keys
|
The "vars" argument must be a map. Within the template file, each of the keys
|
||||||
in the map is available as a variable for interpolation. The template may
|
in the map is available as a variable for interpolation. The template may
|
||||||
also use any other function available in the Terraform language, except that
|
also use any other function available in the Terraform language, except that
|
||||||
recursive calls to `templatefile` are not permitted.
|
recursive calls to `templatefile` are not permitted. Variable names must
|
||||||
|
each start with a letter, followed by zero or more letters, digits, or
|
||||||
|
underscores.
|
||||||
|
|
||||||
Strings in the Terraform language are sequences of Unicode characters, so
|
Strings in the Terraform language are sequences of Unicode characters, so
|
||||||
this function will interpret the file contents as UTF-8 encoded text and
|
this function will interpret the file contents as UTF-8 encoded text and
|
||||||
|
|
Loading…
Reference in New Issue