Module tries to instantiate wrong provider: failed to instantiate provider "xxx" to obtain schema: unavailable provider

I have a module ./modules/monitoring

/
+- modules
|  +- monitoring
|     + backend.tf
|     + main.tf
|     + variables.tf
+- subdir1
|  + main.tf
|  ...
+- subdir2
|  + main.tf
|  ...
...

It contains the following backend.tf

terraform {
  required_providers {
    kubectl = {
      source  = "gavinbunney/kubectl"
      version = "~>1.14.0"
    }
  }
}

which contains a kubectl_manifest-resource:

resource "kubectl_manifest" "monitoring_alertmanagerconfig_project" {
...

I use the module as follows:

module "monitoring" {
  source             = "../modules/monitoring"
  clusterid          = rancher2_cluster.cluster.id
  project_namespaces = local.project_namespaces
  namespaces         = local.namespaces
}

tf plangives me this error

│ Error: failed to read schema 
for kubectl_manifest.monitoring_alertmanagerconfig_project 
in registry.terraform.io/hashicorp/kubectl: failed to instantiate provider 
"registry.terraform.io/hashicorp/kubectl" to obtain schema: 
unavailable provider "registry.terraform.io/hashicorp/kubectl"

It’s a bit weird (though not likely to be a cause of your issue) to be writing configuration that is not about the backend, in a file called backend.tf.

Are you really using the module you think you are, because this says .. not . so you would be using another module from the parent directory instead of the one you showed in your directory listing.

When I copy the code you showed into local files, and fix the .. to ., and run terraform init, it finds the expected provider just fine for me.

while simplifying my example I made it apparently too simple. The .. makes sense, I will update the example.

It’s a bit weird (though not likely to be a cause of your issue) to be writing configuration that is not about the backend, in a file called backend.tf.

I changed that but still the same

Hi @papanito,

It sounds like your other modules are missing their declaration that they depend on gavinbunney/kubectl.

For backward compatibility with modules that were written before Terraform supported third-party providers Terraform assumes that any undeclared dependency is for an official provider (in the hashicorp/ namespace), but modern Terraform modules should always specify all of the providers they depend on.

If I’ve guessed correctly what the problem is then the solution would be to write a similar required_providers block in each module. However, shared modules should not typically constrain the upper bound in their version constraints, because that tends to make things complicated if you want to upgrade later (you’ll need to update all of the modules at once) and so I would recommend setting the shared modules to use only >=-style constraints (instead of ~> constraints) and to specify the minimum provider version that you know the provider is compatible with. (Version constraints are intended for specifying provider version compatibility, not for specifying version selections.)

1 Like

Thanks changed it.

Well for now I only have one module.

The affected dependency seems clearly - at least based on the error - the one I explicitly declared.

In meanwhile I got it working. I am not entirely sure what fixed the issues, cause the backend.tf did not change. Maybe related to my tries to do a terraform init -reconfigure and/or terraform init -upgrade.

I may post more details once I understand what changed

In the filesystem tree you shared there are three modules:

  • modules/monitoring
  • subdir1
  • subdir2

When I say “all modules” I mean all three of those, and any other directories that have .tf files in them. Any directory with at least one .tf file is a Terraform module.

Got it. They all have the providers properly defined. I initially had everything in each module, and then moved “monitoring” to a reusable module.