-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core: Specialized errors for incorrect indexes in resource reference
In prior versions of Terraform we permitted inconsistent use of indexes in resource references, but in as of 0.12 the index usage must correlate properly with whether "count" is set on the resource. Since users are likely to have existing configurations with incorrect usage, here we introduce some specialized error messages for situations where we can detect such issues statically. This seems to cover all of the common patterns we've seen in practice. Some usage patterns will fall back on a less-helpful dynamic error here, but no configurations coming from 0.11 can end up that way because 0.11 did not permit forms such as aws_instance.no_count[count.index].bar that this validation would not be able to "see". Our configuration upgrade tool also contains a fix for this already, but it takes a more conservative approach of adding the index [1] rather than [count.index] because it can't be sure (without human help) if correlation of indices is what was intended.
- Loading branch information
1 parent
b50ac16
commit e39c697
Showing
4 changed files
with
195 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package terraform | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/hcl2/hcl" | ||
"github.com/hashicorp/hcl2/hcl/hclsyntax" | ||
|
||
"github.com/hashicorp/terraform/configs/configschema" | ||
"github.com/hashicorp/terraform/lang" | ||
) | ||
|
||
func TestStaticValidateReferences(t *testing.T) { | ||
tests := []struct { | ||
Ref string | ||
WantErr string | ||
}{ | ||
{ | ||
"aws_instance.no_count", | ||
``, | ||
}, | ||
{ | ||
"aws_instance.count", | ||
``, | ||
}, | ||
{ | ||
"aws_instance.count[0]", | ||
``, | ||
}, | ||
{ | ||
"aws_instance.nonexist", | ||
`Reference to undeclared resource: A managed resource "aws_instance" "nonexist" has not been declared in the root module.`, | ||
}, | ||
{ | ||
"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.`, | ||
}, | ||
{ | ||
"aws_instance.count.foo", | ||
// In this case we return two errors that are somewhat redundant with | ||
// one another, but we'll accept that because they both report the | ||
// problem from different perspectives and so give the user more | ||
// opportunity to understand what's going on here. | ||
`2 problems: | ||
- Missing resource instance key: Because aws_instance.count has "count" set, its attributes must be accessed on specific instances. | ||
For example, to correlate with indices of a referring resource, use: | ||
aws_instance.count[count.index] | ||
- Unsupported attribute: This object has no argument, nested block, or exported attribute named "foo".`, | ||
}, | ||
} | ||
|
||
cfg := testModule(t, "static-validate-refs") | ||
evaluator := &Evaluator{ | ||
Config: cfg, | ||
Schemas: &Schemas{ | ||
Providers: map[string]*ProviderSchema{ | ||
"aws": { | ||
ResourceTypes: map[string]*configschema.Block{ | ||
"aws_instance": {}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.Ref, func(t *testing.T) { | ||
traversal, hclDiags := hclsyntax.ParseTraversalAbs([]byte(test.Ref), "", hcl.Pos{Line: 1, Column: 1}) | ||
if hclDiags.HasErrors() { | ||
t.Fatal(hclDiags.Error()) | ||
} | ||
|
||
refs, diags := lang.References([]hcl.Traversal{traversal}) | ||
if diags.HasErrors() { | ||
t.Fatal(diags.Err()) | ||
} | ||
|
||
data := &evaluationStateData{ | ||
Evaluator: evaluator, | ||
} | ||
|
||
diags = data.StaticValidateReferences(refs, nil) | ||
if diags.HasErrors() { | ||
if test.WantErr == "" { | ||
t.Fatalf("Unexpected diagnostics: %s", diags.Err()) | ||
} | ||
|
||
gotErr := diags.Err().Error() | ||
if gotErr != test.WantErr { | ||
t.Fatalf("Wrong diagnostics\ngot: %s\nwant: %s", gotErr, test.WantErr) | ||
} | ||
return | ||
} | ||
|
||
if test.WantErr != "" { | ||
t.Fatalf("Expected diagnostics, but got none\nwant: %s", test.WantErr) | ||
} | ||
}) | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
terraform/test-fixtures/static-validate-refs/static-validate-refs.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
resource "aws_instance" "no_count" { | ||
} | ||
|
||
resource "aws_instance" "count" { | ||
count = 1 | ||
} |