From 7f4019e1f65f7cdc98426e9152473aca9b1731ff Mon Sep 17 00:00:00 2001 From: nozaq Date: Wed, 16 Feb 2022 01:12:55 +0900 Subject: [PATCH 1/3] jsonconfig: fix keys for default providers Fixes provider config keys to reflect implicit provider inheritance. --- internal/command/jsonconfig/config.go | 62 ++-- .../provider-aliasing-default/child/main.tf | 19 ++ .../child/nested-no-requirements/main.tf | 3 + .../child/nested/main.tf | 11 + .../provider-aliasing-default/main.tf | 19 ++ .../provider-aliasing-default/output.json | 270 ++++++++++++++++++ 6 files changed, 368 insertions(+), 16 deletions(-) create mode 100644 internal/command/testdata/show-json/provider-aliasing-default/child/main.tf create mode 100644 internal/command/testdata/show-json/provider-aliasing-default/child/nested-no-requirements/main.tf create mode 100644 internal/command/testdata/show-json/provider-aliasing-default/child/nested/main.tf create mode 100644 internal/command/testdata/show-json/provider-aliasing-default/main.tf create mode 100644 internal/command/testdata/show-json/provider-aliasing-default/output.json diff --git a/internal/command/jsonconfig/config.go b/internal/command/jsonconfig/config.go index 807444d6e4f1..9670fd5e6428 100644 --- a/internal/command/jsonconfig/config.go +++ b/internal/command/jsonconfig/config.go @@ -231,9 +231,37 @@ func marshalProviderConfigs( p.VersionConstraint = getproviders.VersionConstraintsString(vc) } + if c.Parent != nil { + parentKey := opaqueProviderKey(pr.Name, c.Parent.Path.String()) + p.parentKey = findSourceProviderKey(parentKey, m) + } + m[key] = p } + // In child modules, providers defined in the parent module can be implicitly used. + // Such providers could have no requirements and configuration blocks defined. + if c.Parent != nil { + for req := range reqs { + // Implicit inheritance only applies to the default provider, + // so the provider name must be same as the provider type. + key := opaqueProviderKey(req.Type, c.Path.String()) + if _, exists := m[key]; exists { + continue + } + + parentKey := opaqueProviderKey(req.Type, c.Parent.Path.String()) + p := providerConfig{ + Name: req.Type, + FullName: req.String(), + ModuleAddress: c.Path.String(), + parentKey: findSourceProviderKey(parentKey, m), + } + + m[key] = p + } + } + // Must also visit our child modules, recursively. for name, mc := range c.Module.ModuleCalls { // Keys in c.Children are guaranteed to match those in c.Module.ModuleCalls @@ -259,22 +287,7 @@ func marshalProviderConfigs( key := opaqueProviderKey(moduleProviderName, cc.Path.String()) parentKey := opaqueProviderKey(parentProviderName, cc.Parent.Path.String()) - - // Traverse up the module call tree until we find the provider - // configuration which has no linked parent config. This is then - // the source of the configuration used in this module call, so - // we link to it directly - for { - parent, exists := m[parentKey] - if !exists { - break - } - p.parentKey = parentKey - parentKey = parent.parentKey - if parentKey == "" { - break - } - } + p.parentKey = findSourceProviderKey(parentKey, m) m[key] = p } @@ -527,3 +540,20 @@ func opaqueProviderKey(provider string, addr string) (key string) { } return key } + +// Traverse up the module call tree until we find the provider +// configuration which has no linked parent config. This is then +// the source of the configuration used in this module call, so +// we link to it directly +func findSourceProviderKey(startKey string, m map[string]providerConfig) string { + parentKey := startKey + for { + parent, exists := m[parentKey] + if !exists || parent.parentKey == "" { + break + } + parentKey = parent.parentKey + } + + return parentKey +} diff --git a/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf b/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf new file mode 100644 index 000000000000..1ff9e896966f --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + test = { + source = "hashicorp/test" + } + } +} + +resource "test_instance" "test" { + ami = "bar" +} + +module "with_requirement" { + source = "./nested" +} + +module "no_requirements" { + source = "./nested-no-requirements" +} diff --git a/internal/command/testdata/show-json/provider-aliasing-default/child/nested-no-requirements/main.tf b/internal/command/testdata/show-json/provider-aliasing-default/child/nested-no-requirements/main.tf new file mode 100644 index 000000000000..20781869684d --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-default/child/nested-no-requirements/main.tf @@ -0,0 +1,3 @@ +resource "test_instance" "test" { + ami = "qux" +} diff --git a/internal/command/testdata/show-json/provider-aliasing-default/child/nested/main.tf b/internal/command/testdata/show-json/provider-aliasing-default/child/nested/main.tf new file mode 100644 index 000000000000..1590c5cea371 --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-default/child/nested/main.tf @@ -0,0 +1,11 @@ +terraform { + required_providers { + test = { + source = "hashicorp/test" + } + } +} + +resource "test_instance" "test" { + ami = "baz" +} diff --git a/internal/command/testdata/show-json/provider-aliasing-default/main.tf b/internal/command/testdata/show-json/provider-aliasing-default/main.tf new file mode 100644 index 000000000000..f5e63f0aa3bd --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-default/main.tf @@ -0,0 +1,19 @@ +provider "test" { + region = "somewhere" +} + +provider "test" { + alias = "backup" + region = "elsewhere" +} + +resource "test_instance" "test" { + ami = "foo" +} + +module "child" { + source = "./child" + providers = { + test = test.backup + } +} diff --git a/internal/command/testdata/show-json/provider-aliasing-default/output.json b/internal/command/testdata/show-json/provider-aliasing-default/output.json new file mode 100644 index 000000000000..d59e111b412b --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-default/output.json @@ -0,0 +1,270 @@ +{ + "format_version": "1.0", + "terraform_version": "1.1.0-dev", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "foo" + }, + "sensitive_values": {} + } + ], + "child_modules": [ + { + "resources": [ + { + "address": "module.child.test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "bar" + }, + "sensitive_values": {} + } + ], + "address": "module.child", + "child_modules": [ + { + "resources": [ + { + "address": "module.child.module.with_requirement.test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} + } + ], + "address": "module.child.module.with_requirement" + }, + { + "resources": [ + { + "address": "module.child.module.no_requirements.test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "qux" + }, + "sensitive_values": {} + } + ], + "address": "module.child.module.no_requirements" + } + ] + } + ] + } + }, + "resource_changes": [ + { + "address": "module.child.module.no_requirements.test_instance.test", + "module_address": "module.child.module.no_requirements", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "qux" + }, + "after_unknown": { + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + }, + { + "address": "module.child.module.with_requirement.test_instance.test", + "module_address": "module.child.module.with_requirement", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + }, + { + "address": "module.child.test_instance.test", + "module_address": "module.child", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "bar" + }, + "after_unknown": { + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + }, + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "foo" + }, + "after_unknown": { + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + } + ], + "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test", + "expressions": { + "region": { + "constant_value": "somewhere" + } + } + }, + "test.backup": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test", + "alias": "backup", + "expressions": { + "region": { + "constant_value": "elsewhere" + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test", + "expressions": { + "ami": { + "constant_value": "foo" + } + }, + "schema_version": 0 + } + ], + "module_calls": { + "child": { + "source": "./child", + "module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test.backup", + "expressions": { + "ami": { + "constant_value": "bar" + } + }, + "schema_version": 0 + } + ], + "module_calls": { + "no_requirements": { + "source": "./nested-no-requirements", + "module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test.backup", + "expressions": { + "ami": { + "constant_value": "qux" + } + }, + "schema_version": 0 + } + ] + } + }, + "with_requirement": { + "source": "./nested", + "module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test.backup", + "expressions": { + "ami": { + "constant_value": "baz" + } + }, + "schema_version": 0 + } + ] + } + } + } + } + } + } + } + } +} From 0ce040405cfeacc8c32759aa457ccc81c6b3c81f Mon Sep 17 00:00:00 2001 From: nozaq Date: Sat, 19 Feb 2022 00:19:39 +0900 Subject: [PATCH 2/3] jsonconfig: fix provider mappings with same names --- internal/command/command_test.go | 3 +- internal/command/jsonconfig/config.go | 22 +-- internal/command/jsonconfig/config_test.go | 100 ++++++++++++ internal/command/show_test.go | 3 +- .../provider-aliasing-conflict/child/main.tf | 11 ++ .../provider-aliasing-conflict/main.tf | 11 ++ .../provider-aliasing-conflict/output.json | 143 ++++++++++++++++++ .../provider-aliasing-default/child/main.tf | 3 +- .../provider-aliasing-default/output.json | 13 +- 9 files changed, 291 insertions(+), 18 deletions(-) create mode 100644 internal/command/jsonconfig/config_test.go create mode 100644 internal/command/testdata/show-json/provider-aliasing-conflict/child/main.tf create mode 100644 internal/command/testdata/show-json/provider-aliasing-conflict/main.tf create mode 100644 internal/command/testdata/show-json/provider-aliasing-conflict/output.json diff --git a/internal/command/command_test.go b/internal/command/command_test.go index 4a56ecc73b23..2f75ec30de1b 100644 --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -171,7 +171,8 @@ func testFixturePath(name string) string { func metaOverridesForProvider(p providers.Interface) *testingOverrides { return &testingOverrides{ Providers: map[addrs.Provider]providers.Factory{ - addrs.NewDefaultProvider("test"): providers.FactoryFixed(p), + addrs.NewDefaultProvider("test"): providers.FactoryFixed(p), + addrs.NewProvider(addrs.DefaultProviderRegistryHost, "hashicorp2", "test"): providers.FactoryFixed(p), }, } } diff --git a/internal/command/jsonconfig/config.go b/internal/command/jsonconfig/config.go index 9670fd5e6428..4727bc0982d7 100644 --- a/internal/command/jsonconfig/config.go +++ b/internal/command/jsonconfig/config.go @@ -233,7 +233,7 @@ func marshalProviderConfigs( if c.Parent != nil { parentKey := opaqueProviderKey(pr.Name, c.Parent.Path.String()) - p.parentKey = findSourceProviderKey(parentKey, m) + p.parentKey = findSourceProviderKey(parentKey, p.FullName, m) } m[key] = p @@ -255,7 +255,7 @@ func marshalProviderConfigs( Name: req.Type, FullName: req.String(), ModuleAddress: c.Path.String(), - parentKey: findSourceProviderKey(parentKey, m), + parentKey: findSourceProviderKey(parentKey, req.String(), m), } m[key] = p @@ -287,7 +287,7 @@ func marshalProviderConfigs( key := opaqueProviderKey(moduleProviderName, cc.Path.String()) parentKey := opaqueProviderKey(parentProviderName, cc.Parent.Path.String()) - p.parentKey = findSourceProviderKey(parentKey, m) + p.parentKey = findSourceProviderKey(parentKey, p.FullName, m) m[key] = p } @@ -545,14 +545,18 @@ func opaqueProviderKey(provider string, addr string) (key string) { // configuration which has no linked parent config. This is then // the source of the configuration used in this module call, so // we link to it directly -func findSourceProviderKey(startKey string, m map[string]providerConfig) string { - parentKey := startKey - for { - parent, exists := m[parentKey] - if !exists || parent.parentKey == "" { +func findSourceProviderKey(startKey string, fullName string, m map[string]providerConfig) string { + var parentKey string + + key := startKey + for key != "" { + parent, exists := m[key] + if !exists || parent.FullName != fullName { break } - parentKey = parent.parentKey + + parentKey = key + key = parent.parentKey } return parentKey diff --git a/internal/command/jsonconfig/config_test.go b/internal/command/jsonconfig/config_test.go new file mode 100644 index 000000000000..69aeae3f0318 --- /dev/null +++ b/internal/command/jsonconfig/config_test.go @@ -0,0 +1,100 @@ +package jsonconfig + +import ( + "testing" +) + +func TestFindSourceProviderConfig(t *testing.T) { + tests := []struct { + StartKey string + FullName string + ProviderMap map[string]providerConfig + Want string + }{ + { + StartKey: "null", + FullName: "hashicorp/null", + ProviderMap: map[string]providerConfig{}, + Want: "", + }, + { + StartKey: "null", + FullName: "hashicorp/null", + ProviderMap: map[string]providerConfig{ + "null": { + Name: "null", + FullName: "hashicorp/null", + ModuleAddress: "", + }, + }, + Want: "null", + }, + { + StartKey: "null2", + FullName: "hashicorp/null", + ProviderMap: map[string]providerConfig{ + "null": { + Name: "null", + FullName: "hashicorp/null", + ModuleAddress: "", + }, + }, + Want: "", + }, + { + StartKey: "null", + FullName: "hashicorp2/null", + ProviderMap: map[string]providerConfig{ + "null": { + Name: "null", + FullName: "hashicorp/null", + ModuleAddress: "", + }, + }, + Want: "", + }, + { + StartKey: "module.a:null", + FullName: "hashicorp/null", + ProviderMap: map[string]providerConfig{ + "null": { + Name: "null", + FullName: "hashicorp/null", + ModuleAddress: "", + }, + "module.a:null": { + Name: "module.a:null", + FullName: "hashicorp/null", + ModuleAddress: "module.a", + parentKey: "null", + }, + }, + Want: "null", + }, + { + StartKey: "module.a:null", + FullName: "hashicorp2/null", + ProviderMap: map[string]providerConfig{ + "null": { + Name: "null", + FullName: "hashicorp/null", + ModuleAddress: "", + }, + "module.a:null": { + Name: "module.a:null", + FullName: "hashicorp2/null", + ModuleAddress: "module.a", + parentKey: "null", + }, + }, + Want: "module.a:null", + }, + } + + for _, test := range tests { + got := findSourceProviderKey(test.StartKey, test.FullName, test.ProviderMap) + if got != test.Want { + t.Errorf("wrong result:\nGot: %#v\nWant: %#v\n", got, test.Want) + } + } +} diff --git a/internal/command/show_test.go b/internal/command/show_test.go index 00a9e555a2e5..80ae6a9f2294 100644 --- a/internal/command/show_test.go +++ b/internal/command/show_test.go @@ -493,7 +493,8 @@ func TestShow_json_output(t *testing.T) { expectError := strings.Contains(entry.Name(), "error") providerSource, close := newMockProviderSource(t, map[string][]string{ - "test": {"1.2.3"}, + "test": {"1.2.3"}, + "hashicorp2/test": {"1.2.3"}, }) defer close() diff --git a/internal/command/testdata/show-json/provider-aliasing-conflict/child/main.tf b/internal/command/testdata/show-json/provider-aliasing-conflict/child/main.tf new file mode 100644 index 000000000000..2479df3359f4 --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-conflict/child/main.tf @@ -0,0 +1,11 @@ +terraform { + required_providers { + test = { + source = "hashicorp2/test" + } + } +} + +resource "test_instance" "test" { + ami = "bar" +} diff --git a/internal/command/testdata/show-json/provider-aliasing-conflict/main.tf b/internal/command/testdata/show-json/provider-aliasing-conflict/main.tf new file mode 100644 index 000000000000..2d8bc0b90120 --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-conflict/main.tf @@ -0,0 +1,11 @@ +provider "test" { + region = "somewhere" +} + +resource "test_instance" "test" { + ami = "foo" +} + +module "child" { + source = "./child" +} diff --git a/internal/command/testdata/show-json/provider-aliasing-conflict/output.json b/internal/command/testdata/show-json/provider-aliasing-conflict/output.json new file mode 100644 index 000000000000..6b7ee48c8da0 --- /dev/null +++ b/internal/command/testdata/show-json/provider-aliasing-conflict/output.json @@ -0,0 +1,143 @@ +{ + "format_version": "1.0", + "terraform_version": "1.1.0-dev", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "foo" + }, + "sensitive_values": {} + } + ], + "child_modules": [ + { + "resources": [ + { + "address": "module.child.test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp2/test", + "schema_version": 0, + "values": { + "ami": "bar" + }, + "sensitive_values": {} + } + ], + "address": "module.child" + } + ] + } + }, + "resource_changes": [ + { + "address": "module.child.test_instance.test", + "module_address": "module.child", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp2/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "bar" + }, + "after_unknown": { + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + }, + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "foo" + }, + "after_unknown": { + "id": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + } + ], + "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test", + "expressions": { + "region": { + "constant_value": "somewhere" + } + } + }, + "module.child:test": { + "module_address": "module.child", + "name": "test", + "full_name": "registry.terraform.io/hashicorp2/test" + } + }, + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test", + "expressions": { + "ami": { + "constant_value": "foo" + } + }, + "schema_version": 0 + } + ], + "module_calls": { + "child": { + "source": "./child", + "module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "module.child:test", + "expressions": { + "ami": { + "constant_value": "bar" + } + }, + "schema_version": 0 + } + ] + } + } + } + } + } +} diff --git a/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf b/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf index 1ff9e896966f..b865e3e14a97 100644 --- a/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf +++ b/internal/command/testdata/show-json/provider-aliasing-default/child/main.tf @@ -11,7 +11,8 @@ resource "test_instance" "test" { } module "with_requirement" { - source = "./nested" + source = "./nested" + depends_on = [module.no_requirements] } module "no_requirements" { diff --git a/internal/command/testdata/show-json/provider-aliasing-default/output.json b/internal/command/testdata/show-json/provider-aliasing-default/output.json index d59e111b412b..d6b1706437de 100644 --- a/internal/command/testdata/show-json/provider-aliasing-default/output.json +++ b/internal/command/testdata/show-json/provider-aliasing-default/output.json @@ -38,36 +38,36 @@ { "resources": [ { - "address": "module.child.module.with_requirement.test_instance.test", + "address": "module.child.module.no_requirements.test_instance.test", "mode": "managed", "type": "test_instance", "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "schema_version": 0, "values": { - "ami": "baz" + "ami": "qux" }, "sensitive_values": {} } ], - "address": "module.child.module.with_requirement" + "address": "module.child.module.no_requirements" }, { "resources": [ { - "address": "module.child.module.no_requirements.test_instance.test", + "address": "module.child.module.with_requirement.test_instance.test", "mode": "managed", "type": "test_instance", "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "schema_version": 0, "values": { - "ami": "qux" + "ami": "baz" }, "sensitive_values": {} } ], - "address": "module.child.module.no_requirements" + "address": "module.child.module.with_requirement" } ] } @@ -243,6 +243,7 @@ }, "with_requirement": { "source": "./nested", + "depends_on": ["module.no_requirements"], "module": { "resources": [ { From 3c32f7a56cc0dfbd68f0eeef3534fe488c1f919e Mon Sep 17 00:00:00 2001 From: nozaq Date: Sat, 19 Feb 2022 01:15:58 +0900 Subject: [PATCH 3/3] jsonconfig: add implicitly created provider configs --- internal/command/jsonconfig/config.go | 38 ++++++++++--------- .../show-json/basic-delete/output.json | 6 +++ .../show-json/basic-update/output.json | 6 +++ .../testdata/show-json/drift/output.json | 6 +++ .../show-json/module-depends-on/output.json | 6 +++ .../testdata/show-json/modules/output.json | 5 +++ .../show-json/moved-drift/output.json | 6 +++ .../testdata/show-json/moved/output.json | 6 +++ .../multi-resource-update/output.json | 6 +++ .../show-json/nested-modules/output.json | 15 +++++--- .../show-json/requires-replace/output.json | 6 +++ .../show-json/sensitive-values/output.json | 6 +++ 12 files changed, 88 insertions(+), 24 deletions(-) diff --git a/internal/command/jsonconfig/config.go b/internal/command/jsonconfig/config.go index 4727bc0982d7..f744c91086f8 100644 --- a/internal/command/jsonconfig/config.go +++ b/internal/command/jsonconfig/config.go @@ -239,27 +239,29 @@ func marshalProviderConfigs( m[key] = p } - // In child modules, providers defined in the parent module can be implicitly used. - // Such providers could have no requirements and configuration blocks defined. - if c.Parent != nil { - for req := range reqs { - // Implicit inheritance only applies to the default provider, - // so the provider name must be same as the provider type. - key := opaqueProviderKey(req.Type, c.Path.String()) - if _, exists := m[key]; exists { - continue - } + // Providers could be implicitly created or inherited from the parent module + // when no requirements and configuration block defined. + for req := range reqs { + // Only default providers could implicitly exist, + // so the provider name must be same as the provider type. + key := opaqueProviderKey(req.Type, c.Path.String()) + if _, exists := m[key]; exists { + continue + } - parentKey := opaqueProviderKey(req.Type, c.Parent.Path.String()) - p := providerConfig{ - Name: req.Type, - FullName: req.String(), - ModuleAddress: c.Path.String(), - parentKey: findSourceProviderKey(parentKey, req.String(), m), - } + p := providerConfig{ + Name: req.Type, + FullName: req.String(), + ModuleAddress: c.Path.String(), + } - m[key] = p + // In child modules, providers defined in the parent module can be implicitly used. + if c.Parent != nil { + parentKey := opaqueProviderKey(req.Type, c.Parent.Path.String()) + p.parentKey = findSourceProviderKey(parentKey, p.FullName, m) } + + m[key] = p } // Must also visit our child modules, recursively. diff --git a/internal/command/testdata/show-json/basic-delete/output.json b/internal/command/testdata/show-json/basic-delete/output.json index e1779c04cc2a..4b10cc283a1c 100644 --- a/internal/command/testdata/show-json/basic-delete/output.json +++ b/internal/command/testdata/show-json/basic-delete/output.json @@ -130,6 +130,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "outputs": { "test": { diff --git a/internal/command/testdata/show-json/basic-update/output.json b/internal/command/testdata/show-json/basic-update/output.json index e4b4731426a1..a81cc2b5d174 100644 --- a/internal/command/testdata/show-json/basic-update/output.json +++ b/internal/command/testdata/show-json/basic-update/output.json @@ -96,6 +96,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "outputs": { "test": { diff --git a/internal/command/testdata/show-json/drift/output.json b/internal/command/testdata/show-json/drift/output.json index 2d5c071b4300..08029bf37e77 100644 --- a/internal/command/testdata/show-json/drift/output.json +++ b/internal/command/testdata/show-json/drift/output.json @@ -141,6 +141,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "resources": [ { diff --git a/internal/command/testdata/show-json/module-depends-on/output.json b/internal/command/testdata/show-json/module-depends-on/output.json index d02efaa22f0d..c76c762659d9 100644 --- a/internal/command/testdata/show-json/module-depends-on/output.json +++ b/internal/command/testdata/show-json/module-depends-on/output.json @@ -43,6 +43,12 @@ } ], "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "resources": [ { diff --git a/internal/command/testdata/show-json/modules/output.json b/internal/command/testdata/show-json/modules/output.json index 1728282592de..e4ef8deb18ae 100644 --- a/internal/command/testdata/show-json/modules/output.json +++ b/internal/command/testdata/show-json/modules/output.json @@ -293,6 +293,11 @@ "module_address": "module.module_test_foo", "name": "test", "full_name": "registry.terraform.io/hashicorp/test" + }, + "module.module_test_bar:test": { + "module_address": "module.module_test_bar", + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" } } } diff --git a/internal/command/testdata/show-json/moved-drift/output.json b/internal/command/testdata/show-json/moved-drift/output.json index ad6b0564135e..db3ac21c257e 100644 --- a/internal/command/testdata/show-json/moved-drift/output.json +++ b/internal/command/testdata/show-json/moved-drift/output.json @@ -143,6 +143,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "resources": [ { diff --git a/internal/command/testdata/show-json/moved/output.json b/internal/command/testdata/show-json/moved/output.json index 3e74a4ddb4e4..d8b9f2a245ea 100644 --- a/internal/command/testdata/show-json/moved/output.json +++ b/internal/command/testdata/show-json/moved/output.json @@ -68,6 +68,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "resources": [ { diff --git a/internal/command/testdata/show-json/multi-resource-update/output.json b/internal/command/testdata/show-json/multi-resource-update/output.json index 6da29965e29c..279a8d5593fb 100644 --- a/internal/command/testdata/show-json/multi-resource-update/output.json +++ b/internal/command/testdata/show-json/multi-resource-update/output.json @@ -137,6 +137,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "outputs": { "test": { diff --git a/internal/command/testdata/show-json/nested-modules/output.json b/internal/command/testdata/show-json/nested-modules/output.json index 6d0af8a1468c..cf1ab978c912 100644 --- a/internal/command/testdata/show-json/nested-modules/output.json +++ b/internal/command/testdata/show-json/nested-modules/output.json @@ -37,9 +37,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "bar-var" @@ -53,6 +51,13 @@ } ], "configuration": { + "provider_config": { + "module.my_module.module.more:test": { + "module_address": "module.my_module.module.more", + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "module_calls": { "my_module": { @@ -71,9 +76,7 @@ "provider_config_key": "module.my_module.module.more:test", "expressions": { "ami": { - "references": [ - "var.test_var" - ] + "references": ["var.test_var"] } }, "schema_version": 0 diff --git a/internal/command/testdata/show-json/requires-replace/output.json b/internal/command/testdata/show-json/requires-replace/output.json index e71df784f4f7..1eb37ea1cfbd 100644 --- a/internal/command/testdata/show-json/requires-replace/output.json +++ b/internal/command/testdata/show-json/requires-replace/output.json @@ -70,6 +70,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "resources": [ { diff --git a/internal/command/testdata/show-json/sensitive-values/output.json b/internal/command/testdata/show-json/sensitive-values/output.json index d7e4719c71f5..0047c0b60042 100644 --- a/internal/command/testdata/show-json/sensitive-values/output.json +++ b/internal/command/testdata/show-json/sensitive-values/output.json @@ -81,6 +81,12 @@ } }, "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, "root_module": { "outputs": { "test": {