From 76fca28faae90a341e49bdfd2fe5ecb74c573ca1 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 27 Sep 2018 14:10:51 -0700 Subject: [PATCH] core: Better error message for prematurely-removed provider config This error message appears in a situation that is often confusing for users, since the connection between resources and their providers in the state is not something we draw attention to in the user experience of Terraform. This new error message tries to be a bit clearer about what the user must do to resolve it. It's still not perfect since it doesn't cover the variant of this problem where an entire module containing a provider block and resources has been removed at the same time, but since there isn't an easily-summarizable way to continue in that state this will need to do for the moment, until we find a way to file off that rough edge in the workflow. --- terraform/transform_provider.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index 520ed317b..6a4fb47c4 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -4,11 +4,11 @@ import ( "fmt" "log" - "github.com/hashicorp/go-multierror" "github.com/hashicorp/hcl2/hcl" "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/dag" + "github.com/hashicorp/terraform/tfdiags" ) func TransformProviders(providers []string, concrete ConcreteProviderNodeFunc, config *configs.Config) GraphTransformer { @@ -84,7 +84,7 @@ func (t *ProviderTransformer) Transform(g *Graph) error { // the graph, and then create graph edges from provider to provider user // so that the providers will get initialized first. - var err error + var diags tfdiags.Diagnostics // To start, we'll collect the _requested_ provider addresses for each // node, which we'll then resolve (handling provider inheritence, etc) in @@ -131,8 +131,8 @@ func (t *ProviderTransformer) Transform(g *Graph) error { _, ok := v.(GraphNodeSubPath) if !ok && target == nil { - // No target and no path to traverse up grom - err = multierror.Append(err, fmt.Errorf("%s: provider %s couldn't be found", dag.VertexName(v), p)) + // No target and no path to traverse up from + diags = diags.Append(fmt.Errorf("%s: provider %s couldn't be found", dag.VertexName(v), p)) continue } @@ -171,9 +171,13 @@ func (t *ProviderTransformer) Transform(g *Graph) error { } if target == nil { - err = multierror.Append(err, fmt.Errorf( - "%s: configuration for %s is not present; a provider configuration block is required for all operations", - dag.VertexName(v), p, + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Provider configuration not present", + fmt.Sprintf( + "To work with %s its original provider configuration at %s is required, but it has been removed. This occurs when a provider configuration is removed while objects created by that provider still exist in the state. Re-add the provider configuration to destroy %s, after which you can remove the provider configuration again.", + dag.VertexName(v), p, dag.VertexName(v), + ), )) break } @@ -193,7 +197,7 @@ func (t *ProviderTransformer) Transform(g *Graph) error { } } - return err + return diags.Err() } // CloseProviderTransformer is a GraphTransformer that adds nodes to the