diff --git a/internal/terraform/transform_provider.go b/internal/terraform/transform_provider.go index 3e459e7a7b..2e1f8bd5f3 100644 --- a/internal/terraform/transform_provider.go +++ b/internal/terraform/transform_provider.go @@ -543,6 +543,13 @@ func (t *ProviderConfigTransformer) transformSingle(g *Graph, c *configs.Config) Module: path, } + if _, ok := t.providers[addr.String()]; ok { + // The config validation warns about this too, but we can't + // completely prevent it in v1. + log.Printf("[WARN] ProviderConfigTransformer: duplicate required_providers entry for %s", addr) + continue + } + abstract := &NodeAbstractProvider{ Addr: addr, } @@ -568,6 +575,13 @@ func (t *ProviderConfigTransformer) transformSingle(g *Graph, c *configs.Config) Module: path, } + if _, ok := t.providers[addr.String()]; ok { + // The abstract provider node may already have been added from the + // provider requirements. + log.Printf("[WARN] ProviderConfigTransformer: provider node %s already added", addr) + continue + } + abstract := &NodeAbstractProvider{ Addr: addr, } diff --git a/internal/terraform/transform_provider_test.go b/internal/terraform/transform_provider_test.go index 0436fc0324..3580a548b3 100644 --- a/internal/terraform/transform_provider_test.go +++ b/internal/terraform/transform_provider_test.go @@ -446,6 +446,42 @@ provider["registry.terraform.io/hashicorp/test"].z` } } +func TestProviderConfigTransformer_duplicateLocalName(t *testing.T) { + mod := testModuleInline(t, map[string]string{ + "main.tf": ` +terraform { + required_providers { + # We have to allow this since it wasn't previously prevented. If the + # default config is equivalent to the provider config, the user may never + # see an error. + dupe = { + source = "registry.terraform.io/hashicorp/test" + } + } +} + +provider "test" { +} +`}) + concrete := func(a *NodeAbstractProvider) dag.Vertex { return a } + + g := testProviderTransformerGraph(t, mod) + tf := ProviderConfigTransformer{ + Config: mod, + Concrete: concrete, + } + if err := tf.Transform(g); err != nil { + t.Fatalf("err: %s", err) + } + + expected := `provider["registry.terraform.io/hashicorp/test"]` + + actual := strings.TrimSpace(g.String()) + if actual != expected { + t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual) + } +} + const testTransformProviderBasicStr = ` aws_instance.web provider["registry.terraform.io/hashicorp/aws"]