core: "Did you mean" hint for missing data. prefix in references
It's a relatively common mistake to try to refer to a data resource without including the data. prefix, making Terraform understand it as a reference to a managed resource. To help with that case, we'll include an additonal suggestion if we can see that there's a data resource declared with the same type and name as in the given address.
This commit is contained in:
parent
3e40a9a4eb
commit
358fb54f75
|
@ -203,10 +203,21 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co
|
||||||
|
|
||||||
cfg := modCfg.Module.ResourceByAddr(addr)
|
cfg := modCfg.Module.ResourceByAddr(addr)
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
|
var suggestion string
|
||||||
|
// A common mistake is omitting the data. prefix when trying to refer
|
||||||
|
// to a data resource, so we'll add a special hint for that.
|
||||||
|
if addr.Mode == addrs.ManagedResourceMode {
|
||||||
|
candidateAddr := addr // not a pointer, so this is a copy
|
||||||
|
candidateAddr.Mode = addrs.DataResourceMode
|
||||||
|
if candidateCfg := modCfg.Module.ResourceByAddr(candidateAddr); candidateCfg != nil {
|
||||||
|
suggestion = fmt.Sprintf("\n\nDid you mean the data resource %s?", candidateAddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: `Reference to undeclared resource`,
|
Summary: `Reference to undeclared resource`,
|
||||||
Detail: fmt.Sprintf(`A %s resource %q %q has not been declared in %s.`, modeAdjective, addr.Type, addr.Name, moduleConfigDisplayAddr(modCfg.Path)),
|
Detail: fmt.Sprintf(`A %s resource %q %q has not been declared in %s.%s`, modeAdjective, addr.Type, addr.Name, moduleConfigDisplayAddr(modCfg.Path), suggestion),
|
||||||
Subject: rng.ToHCL().Ptr(),
|
Subject: rng.ToHCL().Ptr(),
|
||||||
})
|
})
|
||||||
return diags
|
return diags
|
||||||
|
|
|
@ -32,6 +32,12 @@ func TestStaticValidateReferences(t *testing.T) {
|
||||||
"aws_instance.nonexist",
|
"aws_instance.nonexist",
|
||||||
`Reference to undeclared resource: A managed resource "aws_instance" "nonexist" has not been declared in the root module.`,
|
`Reference to undeclared resource: A managed resource "aws_instance" "nonexist" has not been declared in the root module.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"beep.boop",
|
||||||
|
`Reference to undeclared resource: A managed resource "beep" "boop" has not been declared in the root module.
|
||||||
|
|
||||||
|
Did you mean the data resource data.beep.boop?`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"aws_instance.no_count[0]",
|
"aws_instance.no_count[0]",
|
||||||
`Unexpected resource instance key: Because aws_instance.no_count does not have "count" or "for_each" set, references to it must not include an index key. Remove the bracketed index to refer to the single instance of this resource.`,
|
`Unexpected resource instance key: Because aws_instance.no_count does not have "count" or "for_each" set, references to it must not include an index key. Remove the bracketed index to refer to the single instance of this resource.`,
|
||||||
|
|
|
@ -18,3 +18,6 @@ resource "boop_instance" "yep" {
|
||||||
|
|
||||||
resource "boop_whatever" "nope" {
|
resource "boop_whatever" "nope" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data "beep" "boop" {
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue