Include Providers from child modules in the root module?

I’m just curious what is best practice here.

Say my root module uses 4 different Providers, and I have them all listed under “required_providers” in the root module’s terraform block.

Now what if I call a child module that uses 2 new/different providers? Should I include those providers in the root module terraform block as well, even though the root module code never uses them?

Hi @nnellans-acts,

For any provider that requires configuration (a provider block) you’ll typically have at least the configuration block in the root module, in which case you’d need to write the required_providers block to tell Terraform which provider the configuration relates to:

terraform {
  required_providers {
    foo = {
      source = "example/foo"
    }
  }
}

# the "foo" below is a reference into the required_providers
# mapping above, so Terraform can see you mean example/foo.
provider "foo" {
  # provider configuration settings...
}

module "uses_foo" {
  source = "./modules/uses-foo"

  # If your module only needs one configuration
  # for example/foo then you can omit the following
  # and let Terraform infer it by default, but
  # for the sake of storytelling...
  providers = {
    # Again here both of these "foo" are reference
    # into the required_providers mapping above,
    # so Terraform can see you mean example/foo.
    foo = foo
  }
}

In order to inherit this provider configuration from the root module, your child module would also need to declare that it depends on example/foo, so Terraform can see that the two modules are referring to the same provider:

terraform {
  required_providers {
    foo = {
      source = "example/foo"
    }
  }
}

In some simpler situations it’s possible to write the root module so that it contains no references to the provider at all. This would be true, for example, if the provider doesn’t require any configuration, because then the child module’s references to example/foo can just pick up the automatically-created empty provider configuration and use it, without needing to say anything about the provider in the root module.

The general form of this answer is: you need to declare required_providers for any module that contains a direct reference to a particular provider, because that’s how Terraform knows how to translate the short names like foo that you’re using within the module into the global name example/foo which uniquely identifies that provider across the whole configuration (and in the Terraform Registry, too).

Thank you once again! Appreciate it.