diff --git a/backend/local/backend.go b/backend/local/backend.go index eb2053b23..8a4050362 100644 --- a/backend/local/backend.go +++ b/backend/local/backend.go @@ -9,7 +9,6 @@ import ( "os" "path/filepath" "sort" - "strings" "sync" "github.com/hashicorp/terraform/backend" @@ -594,25 +593,3 @@ func (b *Local) stateWorkspaceDir() string { return DefaultWorkspaceDir } - -func (b *Local) pluginInitRequired(providerErr *terraform.ResourceProviderError) { - b.CLI.Output(b.Colorize().Color(fmt.Sprintf( - strings.TrimSpace(errPluginInit)+"\n", - providerErr))) -} - -// this relies on multierror to format the plugin errors below the copy -const errPluginInit = ` -[reset][bold][yellow]Plugin reinitialization required. Please run "terraform init".[reset] -[yellow]Reason: Could not satisfy plugin requirements. - -Plugins are external binaries that Terraform uses to access and manipulate -resources. The configuration provided requires plugins which can't be located, -don't satisfy the version constraints, or are otherwise incompatible. - -[reset][red]%s - -[reset][yellow]Terraform automatically discovers provider requirements from your -configuration, including providers used in child modules. To see the -requirements and constraints from each module, run "terraform providers". -` diff --git a/terraform/context.go b/terraform/context.go index 14e3863a6..afdba99c1 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -172,16 +172,18 @@ func NewContext(opts *ContextOpts) (*Context, tfdiags.Diagnostics) { // Bind available provider plugins to the constraints in config var providerFactories map[string]providers.Factory if opts.ProviderResolver != nil { - var err error deps := ConfigTreeDependencies(opts.Config, state) reqd := deps.AllPluginRequirements() if opts.ProviderSHA256s != nil && !opts.SkipProviderVerify { reqd.LockExecutables(opts.ProviderSHA256s) } log.Printf("[TRACE] terraform.NewContext: resolving provider version selections") - providerFactories, err = resourceProviderFactories(opts.ProviderResolver, reqd) - if err != nil { - diags = diags.Append(err) + + var providerDiags tfdiags.Diagnostics + providerFactories, providerDiags = resourceProviderFactories(opts.ProviderResolver, reqd) + diags = diags.Append(providerDiags) + + if diags.HasErrors() { return nil, diags } } else { diff --git a/terraform/resource_provider.go b/terraform/resource_provider.go index e666fb6d2..17f93e10d 100644 --- a/terraform/resource_provider.go +++ b/terraform/resource_provider.go @@ -3,6 +3,8 @@ package terraform import ( "fmt" + "github.com/hashicorp/terraform/tfdiags" + multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform/plugin/discovery" "github.com/hashicorp/terraform/providers" @@ -296,13 +298,35 @@ func ProviderHasDataSource(p ResourceProvider, n string) bool { // This should be called only with configurations that have passed calls // to config.Validate(), which ensures that all of the given version // constraints are valid. It will panic if any invalid constraints are present. -func resourceProviderFactories(resolver providers.Resolver, reqd discovery.PluginRequirements) (map[string]providers.Factory, error) { +func resourceProviderFactories(resolver providers.Resolver, reqd discovery.PluginRequirements) (map[string]providers.Factory, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics ret, errs := resolver.ResolveProviders(reqd) if errs != nil { - return nil, &ResourceProviderError{ - Errors: errs, + diags = diags.Append( + tfdiags.Sourceless(tfdiags.Error, + "Could not satisfy plugin requirements", + errPluginInit, + ), + ) + + for _, err := range errs { + diags = diags.Append(err) } + + return nil, diags } return ret, nil } + +const errPluginInit = ` +Plugin reinitialization required. Please run "terraform init". + +Plugins are external binaries that Terraform uses to access and manipulate +resources. The configuration provided requires plugins which can't be located, +don't satisfy the version constraints, or are otherwise incompatible. + +Terraform automatically discovers provider requirements from your +configuration, including providers used in child modules. To see the +requirements and constraints from each module, run "terraform providers". +`