Skip to content

Commit 23eb9bd

Browse files
committed
check for duplicate defaults from resource names
1 parent d7238d5 commit 23eb9bd

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

internal/configs/config_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func TestConfigProviderRequirements(t *testing.T) {
160160

161161
func TestConfigProviderRequirementsDuplicate(t *testing.T) {
162162
_, diags := testNestedModuleConfigFromDir(t, "testdata/duplicate-local-name")
163-
assertDiagnosticCount(t, diags, 2)
163+
assertDiagnosticCount(t, diags, 3)
164164
assertDiagnosticSummary(t, diags, "Duplicate required provider")
165165
}
166166

internal/configs/provider_validation.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func validateProviderConfigs(parentCall *ModuleCall, cfg *Config, noProviderConf
118118
Severity: hcl.DiagWarning,
119119
Summary: "Duplicate required provider",
120120
Detail: fmt.Sprintf(
121-
"Provider %s with the local name %q was implicitly required via a configuration block as %q. Make sure the provider configuration block name matches the name used in required_providers.",
121+
"Provider %s with the local name %q was implicitly required via a configuration block as %q. The provider configuration block name must match the name used in required_providers.",
122122
req.Type.ForDisplay(), req.Name, req.Type.Type,
123123
),
124124
Subject: &req.DeclRange,
@@ -142,6 +142,44 @@ func validateProviderConfigs(parentCall *ModuleCall, cfg *Config, noProviderConf
142142
}
143143
}
144144

145+
checkImpliedProviderNames := func(resourceConfigs map[string]*Resource) {
146+
// Now that we have all the provider configs and requirements validated,
147+
// check for any resources which use an implied localname which doesn't
148+
// match that of required_providers
149+
for _, r := range resourceConfigs {
150+
// We're looking for resources with no specific provider reference
151+
if r.ProviderConfigRef != nil {
152+
continue
153+
}
154+
155+
localName := r.Addr().ImpliedProvider()
156+
if _, ok := localNames[localName]; ok {
157+
// OK, this was listed directly in the required_providers
158+
continue
159+
}
160+
161+
defAddr := addrs.NewDefaultProvider(localName)
162+
163+
// Now make sure we don't have the same provider required under a
164+
// different name.
165+
for prevLocalName, addr := range localNames {
166+
if addr.Equals(defAddr) {
167+
diags = append(diags, &hcl.Diagnostic{
168+
Severity: hcl.DiagWarning,
169+
Summary: "Duplicate required provider",
170+
Detail: fmt.Sprintf(
171+
"Provider %q was implicitly required via resource %q, but listed in required_providers as %q. Either the local name in required_providers must match the resource name, or the provider must be assigned within the resource block.",
172+
localName, r.Addr(), prevLocalName,
173+
),
174+
Subject: &r.DeclRange,
175+
})
176+
}
177+
}
178+
}
179+
}
180+
checkImpliedProviderNames(mod.ManagedResources)
181+
checkImpliedProviderNames(mod.DataResources)
182+
145183
// collect providers passed from the parent
146184
if parentCall != nil {
147185
for _, passed := range parentCall.Providers {

internal/configs/testdata/duplicate-local-name/main.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ terraform {
99
other = {
1010
source = "hashicorp/default"
1111
}
12+
13+
wrong-name = {
14+
source = "hashicorp/foo"
15+
}
1216
}
1317
}
1418

1519
provider "default" {
1620
}
21+
22+
resource "foo_resource" {
23+
}

0 commit comments

Comments
 (0)