Conditional use of providers in root modules

I have the following code in a root module:

provider "vsphere" {
  user           = var.vsphere_user
  password       = var.VSPHERE_PASSWORD
  vsphere_server = var.vsphere_server

  # If you have a self-signed cert
  allow_unverified_ssl = true
}

module "kubernetes_cluster_vm_pool" {
  source = "./modules/kubernetes_cluster_vm_pool"
}

module "kubernetes_cluster" {
  source = "./modules/kubernetes_cluster"
}

module "app" {
  source = "./modules/app"
}

}

I want to allow people to use this who for example may not want to use the kubernetes_cluster_vm_pool module which talks to the VMware vSphere provider, so tey may wish to skip this, the problem being that terraform plan and apply will still try to connect to the vSphere vCenter, is there any way around this other than to instruct people to rewrite the root module to include what they want / exclude what they don’t want, my end goal is for people to be able to deploy the different modules and not worry about having to connect to vSphere if they are not using it.

What are you meaning by “root module” here? I normally understand that to mean a code directory that you would run the terraform init/plan/apply commends within, as opposed to a normal module which would only ever be utilised by another module or a root module. A root module would contain the provider definitions as well as the Terraform backend config, while other modules would not (limited to required_providers in a terraform block).

As a result of that I’m a bit confused about what you are asking. If it is a root module which includes references to modules which require vsphere access then the vsphere provider block is required and the user will need access - otherwise they wouldn’t be able to run the code.

Or are you talking about producing a selection of modules for other people to use? If so you normally wouldn’t have a root module in that repository (no provider blocks to backend config) and wouldn’t define any particular usage - it would be up to the end user to pick and choose which of your modules (and any others) they want to use. Hopefully your documentation (plus the use of required_providers) would inform them of what is needed, so they can set up their root module correctly.

I suspect I’m applying the term “root module” incorrectly here, to ask my question in a less confusing manner, in my file where I define my modules is there any way of achieving the same result of going into the directories containing the module code and running terraform apply, for example if I want to deploy the app module without the terraform provider having to connect to VMware vSphere - I can run terraform init and then apply in the modules/app directory.

The location you run Terraform is where it expects to find provider and backend configuration, as well as where the .terraform directory lives (which contains a cache of the state).

It sounds like what you are wanting is multiple root modules (where you run Terraform from), splitting up your different resources/module usage by type of provider (e.g. one for VMware and one for AWS).