lang/funcs: Filesystem functions hint about dynamically-generated files
The functions that interact with the filesystem are, by design, restricted to reading files that are distributed as a static part of the configuration, and cannot be used to interact with files that are generated dynamically by resources in the configuration. However, new users have often yet developed a correct mental model of how Terraform execution works and are confused by the terse error messages these functions return. As an interim step to help some of those users, this just adds some more commentary to the error message which gives a vague, generic directive to look to attributes of the resource that is generating the file, which should (if it's designed well) export attributes that allow the resulting file to be used effectively with common patterns, such as checksums of the content of the generated file. The error message here is not particularly attractive due to the limitations of the context where it's being returned from, but I'm accepting that here in the interest of keeping this change simple, so we can give a hint about a case that seems to frequently generate new-user questions. We may iterate further on the presentation of this message later.
This commit is contained in:
parent
8c3648c1e6
commit
8f77bd344e
|
@ -32,6 +32,7 @@ func MakeFileFunc(baseDir string, encBase64 bool) function.Function {
|
||||||
path := args[0].AsString()
|
path := args[0].AsString()
|
||||||
src, err := readFileBytes(baseDir, path)
|
src, err := readFileBytes(baseDir, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = function.NewArgError(0, err)
|
||||||
return cty.UnknownVal(cty.String), err
|
return cty.UnknownVal(cty.String), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +370,7 @@ func readFileBytes(baseDir, path string) ([]byte, error) {
|
||||||
// ReadFile does not return Terraform-user-friendly error
|
// ReadFile does not return Terraform-user-friendly error
|
||||||
// messages, so we'll provide our own.
|
// messages, so we'll provide our own.
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("no file exists at %s", path)
|
return nil, fmt.Errorf("no file exists at %s; this function works only with files that are distributed as part of the configuration source code, so if this file will be created by a resource in this configuration you must instead obtain this result from an attribute of that resource", path)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("failed to read %s", path)
|
return nil, fmt.Errorf("failed to read %s", path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ func TestTemplateFile(t *testing.T) {
|
||||||
cty.StringVal("testdata/missing"),
|
cty.StringVal("testdata/missing"),
|
||||||
cty.EmptyObjectVal,
|
cty.EmptyObjectVal,
|
||||||
cty.NilVal,
|
cty.NilVal,
|
||||||
`no file exists at testdata/missing`,
|
`no file exists at testdata/missing; this function works only with files that are distributed as part of the configuration source code, so if this file will be created by a resource in this configuration you must instead obtain this result from an attribute of that resource`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cty.StringVal("testdata/hello.tmpl"),
|
cty.StringVal("testdata/hello.tmpl"),
|
||||||
|
|
Loading…
Reference in New Issue