From 392240a7c10a4ba63764d8472cbcf42b83e05ad2 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Tue, 13 Oct 2020 09:21:05 -0400 Subject: [PATCH] terraform: fix ProviderConfigTransformer The ProviderConfigTransformer was using only the provider FQN to attach a provider configuration to the provider, but what it needs to do is find the local name for the given provider FQN (which may not match the type name) and use that when searching for matching provider configuration. Fixes #26556 This will also be backported to the v0.13 branch. --- terraform/context_validate_test.go | 32 +++++++++++++++++++ .../validate-required-provider-config/main.tf | 20 ++++++++++++ terraform/transform_provider.go | 5 ++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 terraform/testdata/validate-required-provider-config/main.tf diff --git a/terraform/context_validate_test.go b/terraform/context_validate_test.go index 23eeab878ddd..48ff73371757 100644 --- a/terraform/context_validate_test.go +++ b/terraform/context_validate_test.go @@ -650,6 +650,38 @@ func TestContext2Validate_providerConfig_good(t *testing.T) { } } +// In this test there is a mismatch between the provider's fqn (hashicorp/test) +// and it's local name set in required_providers (arbitrary). +func TestContext2Validate_requiredProviderConfig(t *testing.T) { + m := testModule(t, "validate-required-provider-config") + p := testProvider("aws") + + p.GetSchemaReturn = &ProviderSchema{ + Provider: &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "required_attribute": {Type: cty.String, Required: true}, + }, + }, + ResourceTypes: map[string]*configschema.Block{ + "aws_instance": { + Attributes: map[string]*configschema.Attribute{}, + }, + }, + } + + c := testContext2(t, &ContextOpts{ + Config: m, + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), + }, + }) + + diags := c.Validate() + if diags.HasErrors() { + t.Fatalf("unexpected error: %s", diags.Err()) + } +} + func TestContext2Validate_provisionerConfig_bad(t *testing.T) { m := testModule(t, "validate-bad-prov-conf") p := testProvider("aws") diff --git a/terraform/testdata/validate-required-provider-config/main.tf b/terraform/testdata/validate-required-provider-config/main.tf new file mode 100644 index 000000000000..898a23fdf251 --- /dev/null +++ b/terraform/testdata/validate-required-provider-config/main.tf @@ -0,0 +1,20 @@ +# This test verifies that the provider local name, local config and fqn map +# together properly when the local name does not match the type. + +terraform { + required_providers { + arbitrary = { + source = "hashicorp/aws" + } + } +} + +# hashicorp/test has required provider config attributes. This "arbitrary" +# provider configuration block should map to hashicorp/test. +provider "arbitrary" { + required_attribute = "bloop" +} + +resource "aws_instance" "test" { + provider = "arbitrary" +} diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index fdfde6114909..883c4f28fdb9 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -721,9 +721,12 @@ func (t *ProviderConfigTransformer) attachProviderConfigs(g *Graph) error { continue } + // Find the localName for the provider fqn + localName := mc.Module.LocalNameForProvider(addr.Provider) + // Go through the provider configs to find the matching config for _, p := range mc.Module.ProviderConfigs { - if p.Name == addr.Provider.Type && p.Alias == addr.Alias { + if p.Name == localName && p.Alias == addr.Alias { log.Printf("[TRACE] ProviderConfigTransformer: attaching to %q provider configuration from %s", dag.VertexName(v), p.DeclRange) apn.AttachProvider(p) break