From 80ab551867abcfcb631f3e0b22623a34f0c616e0 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Mon, 3 Feb 2020 08:18:04 -0500 Subject: [PATCH] terraform: use addrs.Provider as map keys for provider schemas (#24002) This is a stepping-stone PR for the provider source project. In this PR "legcay-stype" FQNs are created from the provider name string. Future work involves encoding the FQN directly in the AbsProviderConfig and removing the calls to addrs.NewLegacyProvider(). --- backend/local/backend_plan.go | 5 ++- command/format/state.go | 4 +- command/format/state_test.go | 4 +- command/jsonconfig/config.go | 8 +++- command/jsonplan/plan.go | 4 +- command/jsonplan/values.go | 4 +- command/jsonplan/values_test.go | 4 +- command/jsonprovider/provider.go | 2 +- command/jsonprovider/provider_test.go | 5 ++- command/jsonstate/state.go | 4 +- command/jsonstate/state_test.go | 4 +- configs/config.go | 2 +- terraform/context_input.go | 4 +- terraform/eval_context_builtin.go | 2 +- terraform/evaluate.go | 4 +- terraform/evaluate_valid.go | 6 +-- terraform/evaluate_valid_test.go | 5 ++- terraform/graph_builder_apply_test.go | 2 +- terraform/graph_builder_plan_test.go | 18 ++++----- terraform/schemas.go | 38 +++++++++---------- terraform/schemas_test.go | 5 ++- terraform/transform_attach_schema.go | 12 ++++-- .../transform_transitive_reduction_test.go | 4 +- 23 files changed, 87 insertions(+), 63 deletions(-) diff --git a/backend/local/backend_plan.go b/backend/local/backend_plan.go index b15466e9e..38cc244ba 100644 --- a/backend/local/backend_plan.go +++ b/backend/local/backend_plan.go @@ -262,7 +262,10 @@ func RenderPlan(plan *plans.Plan, state *states.State, schemas *terraform.Schema if rcs.Action == plans.NoOp { continue } - providerSchema := schemas.ProviderSchema(rcs.ProviderAddr.ProviderConfig.LocalName) + + // FIXME: update this once the provider fqn is available in the AbsProviderConfig + providerFqn := addrs.NewLegacyProvider(rcs.ProviderAddr.ProviderConfig.LocalName) + providerSchema := schemas.ProviderSchema(providerFqn) if providerSchema == nil { // Should never happen ui.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.ProviderAddr)) diff --git a/command/format/state.go b/command/format/state.go index d5bc26cea..749dffbe4 100644 --- a/command/format/state.go +++ b/command/format/state.go @@ -139,7 +139,9 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf } var schema *configschema.Block - provider := addrs.NewDefaultLocalProviderConfig(addr.DefaultProvider().LegacyString()).Absolute(m.Addr).ProviderConfig.StringCompact() + + // TODO: Get the provider FQN when it is available from the AbsoluteProviderConfig, in state + provider := addr.DefaultProvider() if _, exists := schemas.Providers[provider]; !exists { // This should never happen in normal use because we should've // loaded all of the schemas and checked things prior to this diff --git a/command/format/state_test.go b/command/format/state_test.go index b40bc4891..37384ac47 100644 --- a/command/format/state_test.go +++ b/command/format/state_test.go @@ -138,8 +138,8 @@ func testProviderSchema() *terraform.ProviderSchema { func testSchemas() *terraform.Schemas { provider := testProvider() return &terraform.Schemas{ - Providers: map[string]*terraform.ProviderSchema{ - "test": provider.GetSchemaReturn, + Providers: map[addrs.Provider]*terraform.ProviderSchema{ + addrs.NewLegacyProvider("test"): provider.GetSchemaReturn, }, } } diff --git a/command/jsonconfig/config.go b/command/jsonconfig/config.go index dd2d5cc24..21775db7d 100644 --- a/command/jsonconfig/config.go +++ b/command/jsonconfig/config.go @@ -139,7 +139,9 @@ func marshalProviderConfigs( } for k, pc := range c.Module.ProviderConfigs { - schema := schemas.ProviderConfig(pc.Name) + // FIXME: lookup providerFqn from config + providerFqn := addrs.NewLegacyProvider(pc.Name) + schema := schemas.ProviderConfig(providerFqn) p := providerConfig{ Name: pc.Name, Alias: pc.Alias, @@ -301,8 +303,10 @@ func marshalResources(resources map[string]*configs.Resource, schemas *terraform } } + // TODO: get actual providerFqn + providerFqn := addrs.NewLegacyProvider(v.ProviderConfigAddr().LocalName) schema, schemaVer := schemas.ResourceTypeConfig( - v.ProviderConfigAddr().LocalName, + providerFqn, v.Mode, v.Type, ) diff --git a/command/jsonplan/plan.go b/command/jsonplan/plan.go index 66598aefc..2b9c3dad0 100644 --- a/command/jsonplan/plan.go +++ b/command/jsonplan/plan.go @@ -177,8 +177,10 @@ func (p *plan) marshalResourceChanges(changes *plans.Changes, schemas *terraform continue } + // FIXME: update this once the provider fqn is available in the AbsProviderConfig + providerFqn := addrs.NewLegacyProvider(rc.ProviderAddr.ProviderConfig.LocalName) schema, _ := schemas.ResourceTypeConfig( - rc.ProviderAddr.ProviderConfig.LocalName, + providerFqn, addr.Resource.Resource.Mode, addr.Resource.Resource.Type, ) diff --git a/command/jsonplan/values.go b/command/jsonplan/values.go index e8f8c111a..8403c0dd3 100644 --- a/command/jsonplan/values.go +++ b/command/jsonplan/values.go @@ -180,8 +180,10 @@ func marshalPlanResources(changes *plans.Changes, ris []addrs.AbsResourceInstanc ) } + // FIXME: update this once the provider fqn is available in the AbsProviderConfig + providerFqn := addrs.NewLegacyProvider(r.ProviderAddr.ProviderConfig.LocalName) schema, schemaVer := schemas.ResourceTypeConfig( - r.ProviderAddr.ProviderConfig.LocalName, + providerFqn, r.Addr.Resource.Resource.Mode, resource.Type, ) diff --git a/command/jsonplan/values_test.go b/command/jsonplan/values_test.go index a6bf98ae9..324d4dbaf 100644 --- a/command/jsonplan/values_test.go +++ b/command/jsonplan/values_test.go @@ -290,8 +290,8 @@ func TestMarshalPlanResources(t *testing.T) { func testSchemas() *terraform.Schemas { return &terraform.Schemas{ - Providers: map[string]*terraform.ProviderSchema{ - "test": &terraform.ProviderSchema{ + Providers: map[addrs.Provider]*terraform.ProviderSchema{ + addrs.NewLegacyProvider("test"): &terraform.ProviderSchema{ ResourceTypes: map[string]*configschema.Block{ "test_thing": { Attributes: map[string]*configschema.Attribute{ diff --git a/command/jsonprovider/provider.go b/command/jsonprovider/provider.go index 5c45fd472..7f331e7e0 100644 --- a/command/jsonprovider/provider.go +++ b/command/jsonprovider/provider.go @@ -35,7 +35,7 @@ func Marshal(s *terraform.Schemas) ([]byte, error) { providers := newProviders() for k, v := range s.Providers { - providers.Schemas[k] = marshalProvider(v) + providers.Schemas[k.LegacyString()] = marshalProvider(v) } ret, err := json.Marshal(providers) diff --git a/command/jsonprovider/provider_test.go b/command/jsonprovider/provider_test.go index 64b21d746..120e4fa73 100644 --- a/command/jsonprovider/provider_test.go +++ b/command/jsonprovider/provider_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/zclconf/go-cty/cty" + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/terraform" ) @@ -117,8 +118,8 @@ func TestMarshalProvider(t *testing.T) { func testProviders() *terraform.Schemas { return &terraform.Schemas{ - Providers: map[string]*terraform.ProviderSchema{ - "test": testProvider(), + Providers: map[addrs.Provider]*terraform.ProviderSchema{ + addrs.NewLegacyProvider("test"): testProvider(), }, } } diff --git a/command/jsonstate/state.go b/command/jsonstate/state.go index a7f1f88b5..9df3d8e49 100644 --- a/command/jsonstate/state.go +++ b/command/jsonstate/state.go @@ -273,8 +273,10 @@ func marshalResources(resources map[string]*states.Resource, schemas *terraform. current.Index = k } + // FIXME: lookup providerFqn from state + providerFqn := addrs.NewLegacyProvider(r.ProviderConfig.ProviderConfig.LocalName) schema, _ := schemas.ResourceTypeConfig( - r.ProviderConfig.ProviderConfig.LocalName, + providerFqn, r.Addr.Mode, r.Addr.Type, ) diff --git a/command/jsonstate/state_test.go b/command/jsonstate/state_test.go index 85c549080..d5bdf7fb5 100644 --- a/command/jsonstate/state_test.go +++ b/command/jsonstate/state_test.go @@ -351,8 +351,8 @@ func TestMarshalResources(t *testing.T) { func testSchemas() *terraform.Schemas { return &terraform.Schemas{ - Providers: map[string]*terraform.ProviderSchema{ - "test": &terraform.ProviderSchema{ + Providers: map[addrs.Provider]*terraform.ProviderSchema{ + addrs.NewLegacyProvider("test"): &terraform.ProviderSchema{ ResourceTypes: map[string]*configschema.Block{ "test_thing": { Attributes: map[string]*configschema.Attribute{ diff --git a/configs/config.go b/configs/config.go index e8f3d1d7a..43489e018 100644 --- a/configs/config.go +++ b/configs/config.go @@ -163,7 +163,7 @@ func (c *Config) DescendentForInstance(path addrs.ModuleInstance) *Config { return current } -// ProviderTypes returns the names of each distinct provider type referenced +// ProviderTypes returns the FQNs of each distinct provider type referenced // in the receiving configuration. // // This is a helper for easily determining which provider types are required diff --git a/terraform/context_input.go b/terraform/context_input.go index 90ea72def..4ea838f2b 100644 --- a/terraform/context_input.go +++ b/terraform/context_input.go @@ -96,7 +96,9 @@ func (c *Context) Input(mode InputMode) tfdiags.Diagnostics { UIInput: c.uiInput, } - schema := c.schemas.ProviderConfig(pa.LocalName) + // TODO: get provider FQN + providerFqn := addrs.NewLegacyProvider(pa.LocalName) + schema := c.schemas.ProviderConfig(providerFqn) if schema == nil { // Could either be an incorrect config or just an incomplete // mock in tests. We'll let a later pass decide, and just diff --git a/terraform/eval_context_builtin.go b/terraform/eval_context_builtin.go index 97e89fcbe..087d5a025 100644 --- a/terraform/eval_context_builtin.go +++ b/terraform/eval_context_builtin.go @@ -149,7 +149,7 @@ func (ctx *BuiltinEvalContext) ProviderSchema(addr addrs.AbsProviderConfig) *Pro // FIXME: Once AbsProviderConfig starts containing an FQN, use that directly // here instead of addr.ProviderConfig.LocalName. - return ctx.Schemas.ProviderSchema(addr.ProviderConfig.LocalName) + return ctx.Schemas.ProviderSchema(addrs.NewLegacyProvider(addr.ProviderConfig.LocalName)) } func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error { diff --git a/terraform/evaluate.go b/terraform/evaluate.go index 663f05aac..cf42ba0a6 100644 --- a/terraform/evaluate.go +++ b/terraform/evaluate.go @@ -781,9 +781,9 @@ func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng t func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block { // FIXME: Once AbsProviderConfig has an addrs.Provider in it, we should // be looking schemas up using provider FQNs rather than legacy names. - providerType := providerAddr.ProviderConfig.LocalName + providerFqn := addrs.NewLegacyProvider(providerAddr.ProviderConfig.LocalName) schemas := d.Evaluator.Schemas - schema, _ := schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type) + schema, _ := schemas.ResourceTypeConfig(providerFqn, addr.Mode, addr.Type) return schema } diff --git a/terraform/evaluate_valid.go b/terraform/evaluate_valid.go index d5ace7fab..86c580fa2 100644 --- a/terraform/evaluate_valid.go +++ b/terraform/evaluate_valid.go @@ -217,8 +217,8 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co // legacy addresses. d.Evaluator.Schemas.ResourceTypeConfig below ought to // change to take an addrs.Provider, and then that's what we should be // passing in here. - providerType := cfg.ProviderConfigAddr().LocalName - schema, _ := d.Evaluator.Schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type) + providerFqn := addrs.NewLegacyProvider(cfg.ProviderConfigAddr().LocalName) + schema, _ := d.Evaluator.Schemas.ResourceTypeConfig(providerFqn, addr.Mode, addr.Type) if schema == nil { // Prior validation should've taken care of a resource block with an @@ -227,7 +227,7 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: `Invalid resource type`, - Detail: fmt.Sprintf(`A %s resource type %q is not supported by provider %q.`, modeAdjective, addr.Type, providerType), + Detail: fmt.Sprintf(`A %s resource type %q is not supported by provider %q.`, modeAdjective, addr.Type, providerFqn.LegacyString()), Subject: rng.ToHCL().Ptr(), }) return diags diff --git a/terraform/evaluate_valid_test.go b/terraform/evaluate_valid_test.go index 2f8a50cae..7ba0c604e 100644 --- a/terraform/evaluate_valid_test.go +++ b/terraform/evaluate_valid_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/lang" ) @@ -55,8 +56,8 @@ For example, to correlate with indices of a referring resource, use: evaluator := &Evaluator{ Config: cfg, Schemas: &Schemas{ - Providers: map[string]*ProviderSchema{ - "aws": { + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("aws"): { ResourceTypes: map[string]*configschema.Block{ "aws_instance": {}, }, diff --git a/terraform/graph_builder_apply_test.go b/terraform/graph_builder_apply_test.go index 716405263..b7e3bad2a 100644 --- a/terraform/graph_builder_apply_test.go +++ b/terraform/graph_builder_apply_test.go @@ -500,7 +500,7 @@ func TestApplyGraphBuilder_targetModule(t *testing.T) { // that resource is destroyed. func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) { schemas := simpleTestSchemas() - instanceSchema := schemas.Providers["test"].ResourceTypes["test_object"] + instanceSchema := schemas.Providers[addrs.NewLegacyProvider("test")].ResourceTypes["test_object"] bBefore, _ := plans.NewDynamicValue( cty.ObjectVal(map[string]cty.Value{ diff --git a/terraform/graph_builder_plan_test.go b/terraform/graph_builder_plan_test.go index 336f5be82..0f943a83d 100644 --- a/terraform/graph_builder_plan_test.go +++ b/terraform/graph_builder_plan_test.go @@ -44,9 +44,9 @@ func TestPlanGraphBuilder(t *testing.T) { Config: testModule(t, "graph-builder-plan-basic"), Components: components, Schemas: &Schemas{ - Providers: map[string]*ProviderSchema{ - "aws": awsProvider.GetSchemaReturn, - "openstack": openstackProvider.GetSchemaReturn, + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("aws"): awsProvider.GetSchemaReturn, + addrs.NewLegacyProvider("openstack"): openstackProvider.GetSchemaReturn, }, }, DisableReduce: true, @@ -101,8 +101,8 @@ func TestPlanGraphBuilder_dynamicBlock(t *testing.T) { Config: testModule(t, "graph-builder-plan-dynblock"), Components: components, Schemas: &Schemas{ - Providers: map[string]*ProviderSchema{ - "test": provider.GetSchemaReturn, + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("test"): provider.GetSchemaReturn, }, }, DisableReduce: true, @@ -180,8 +180,8 @@ func TestPlanGraphBuilder_attrAsBlocks(t *testing.T) { Config: testModule(t, "graph-builder-plan-attr-as-blocks"), Components: components, Schemas: &Schemas{ - Providers: map[string]*ProviderSchema{ - "test": provider.GetSchemaReturn, + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("test"): provider.GetSchemaReturn, }, }, DisableReduce: true, @@ -267,8 +267,8 @@ func TestPlanGraphBuilder_forEach(t *testing.T) { Config: testModule(t, "plan-for-each"), Components: components, Schemas: &Schemas{ - Providers: map[string]*ProviderSchema{ - "aws": awsProvider.GetSchemaReturn, + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("aws"): awsProvider.GetSchemaReturn, }, }, DisableReduce: true, diff --git a/terraform/schemas.go b/terraform/schemas.go index f5d8f4f94..2bdd187f1 100644 --- a/terraform/schemas.go +++ b/terraform/schemas.go @@ -15,7 +15,7 @@ import ( // Schemas is a container for various kinds of schema that Terraform needs // during processing. type Schemas struct { - Providers map[string]*ProviderSchema + Providers map[addrs.Provider]*ProviderSchema Provisioners map[string]*configschema.Block } @@ -24,17 +24,17 @@ type Schemas struct { // // It's usually better to go use the more precise methods offered by type // Schemas to handle this detail automatically. -func (ss *Schemas) ProviderSchema(typeName string) *ProviderSchema { +func (ss *Schemas) ProviderSchema(provider addrs.Provider) *ProviderSchema { if ss.Providers == nil { return nil } - return ss.Providers[typeName] + return ss.Providers[provider] } // ProviderConfig returns the schema for the provider configuration of the // given provider type, or nil if no such schema is available. -func (ss *Schemas) ProviderConfig(typeName string) *configschema.Block { - ps := ss.ProviderSchema(typeName) +func (ss *Schemas) ProviderConfig(provider addrs.Provider) *configschema.Block { + ps := ss.ProviderSchema(provider) if ps == nil { return nil } @@ -50,8 +50,8 @@ func (ss *Schemas) ProviderConfig(typeName string) *configschema.Block { // a resource using the "provider" meta-argument. Therefore it's important to // always pass the correct provider name, even though it many cases it feels // redundant. -func (ss *Schemas) ResourceTypeConfig(providerType string, resourceMode addrs.ResourceMode, resourceType string) (block *configschema.Block, schemaVersion uint64) { - ps := ss.ProviderSchema(providerType) +func (ss *Schemas) ResourceTypeConfig(provider addrs.Provider, resourceMode addrs.ResourceMode, resourceType string) (block *configschema.Block, schemaVersion uint64) { + ps := ss.ProviderSchema(provider) if ps == nil || ps.ResourceTypes == nil { return nil, 0 } @@ -76,7 +76,7 @@ func (ss *Schemas) ProvisionerConfig(name string) *configschema.Block { // still valid but may be incomplete. func LoadSchemas(config *configs.Config, state *states.State, components contextComponentFactory) (*Schemas, error) { schemas := &Schemas{ - Providers: map[string]*ProviderSchema{}, + Providers: map[addrs.Provider]*ProviderSchema{}, Provisioners: map[string]*configschema.Block{}, } var diags tfdiags.Diagnostics @@ -89,16 +89,14 @@ func LoadSchemas(config *configs.Config, state *states.State, components context return schemas, diags.Err() } -func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Config, state *states.State, components contextComponentFactory) tfdiags.Diagnostics { +func loadProviderSchemas(schemas map[addrs.Provider]*ProviderSchema, config *configs.Config, state *states.State, components contextComponentFactory) tfdiags.Diagnostics { var diags tfdiags.Diagnostics - ensure := func(typeAddr addrs.Provider) { - // FIXME: Once schema lookup is ready to look up by addrs.Provider rather - // than legacy name, we'll use typeAddr directly. For now, we support - // only legacy addresses. - typeName := typeAddr.LegacyString() + ensure := func(fqn addrs.Provider) { + // TODO: LegacyString() will be removed in an upcoming release + typeName := fqn.LegacyString() - if _, exists := schemas[typeName]; exists { + if _, exists := schemas[fqn]; exists { return } @@ -107,7 +105,7 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con if err != nil { // We'll put a stub in the map so we won't re-attempt this on // future calls. - schemas[typeName] = &ProviderSchema{} + schemas[fqn] = &ProviderSchema{} diags = diags.Append( fmt.Errorf("Failed to instantiate provider %q to obtain schema: %s", typeName, err), ) @@ -121,7 +119,7 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con if resp.Diagnostics.HasErrors() { // We'll put a stub in the map so we won't re-attempt this on // future calls. - schemas[typeName] = &ProviderSchema{} + schemas[fqn] = &ProviderSchema{} diags = diags.Append( fmt.Errorf("Failed to retrieve schema from provider %q: %s", typeName, resp.Diagnostics.Err()), ) @@ -165,12 +163,12 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con } } - schemas[typeName] = s + schemas[fqn] = s } if config != nil { - for _, typeName := range config.ProviderTypes() { - ensure(typeName) + for _, fqn := range config.ProviderTypes() { + ensure(fqn) } } diff --git a/terraform/schemas_test.go b/terraform/schemas_test.go index 3f79981ca..c34c55bcf 100644 --- a/terraform/schemas_test.go +++ b/terraform/schemas_test.go @@ -1,6 +1,7 @@ package terraform import ( + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs/configschema" ) @@ -8,8 +9,8 @@ func simpleTestSchemas() *Schemas { provider := simpleMockProvider() provisioner := simpleMockProvisioner() return &Schemas{ - Providers: map[string]*ProviderSchema{ - "test": provider.GetSchemaReturn, + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("test"): provider.GetSchemaReturn, }, Provisioners: map[string]*configschema.Block{ "test": provisioner.GetSchemaResponse.Provisioner, diff --git a/terraform/transform_attach_schema.go b/terraform/transform_attach_schema.go index 195f9902f..6181ebe59 100644 --- a/terraform/transform_attach_schema.go +++ b/terraform/transform_attach_schema.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/dag" ) @@ -59,9 +60,11 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { mode := addr.Resource.Mode typeName := addr.Resource.Type providerAddr, _ := tv.ProvidedBy() - providerType := providerAddr.ProviderConfig.LocalName - schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName) + // TODO: get providerFQN directly from AbsProviderConfig + providerFqn := addrs.NewLegacyProvider(providerAddr.ProviderConfig.LocalName) + + schema, version := t.Schemas.ResourceTypeConfig(providerFqn, mode, typeName) if schema == nil { log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr) continue @@ -72,7 +75,10 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok { providerAddr := tv.ProviderAddr() - schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.LocalName) + // TODO: get providerFQN directly from AbsProviderConfig + providerFqn := addrs.NewLegacyProvider(providerAddr.ProviderConfig.LocalName) + schema := t.Schemas.ProviderConfig(providerFqn) + if schema == nil { log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr) continue diff --git a/terraform/transform_transitive_reduction_test.go b/terraform/transform_transitive_reduction_test.go index 250978701..3f4cdb0dc 100644 --- a/terraform/transform_transitive_reduction_test.go +++ b/terraform/transform_transitive_reduction_test.go @@ -31,8 +31,8 @@ func TestTransitiveReductionTransformer(t *testing.T) { { transform := &AttachSchemaTransformer{ Schemas: &Schemas{ - Providers: map[string]*ProviderSchema{ - "aws": { + Providers: map[addrs.Provider]*ProviderSchema{ + addrs.NewLegacyProvider("aws"): { ResourceTypes: map[string]*configschema.Block{ "aws_instance": &configschema.Block{ Attributes: map[string]*configschema.Attribute{