Terraform providers questions

Hi support,
I kinda of understand how terraform provider works. but not really when I work on the real project. For example, in the post, Terraform “required_providers” block, configuration_aliases argument

  1. only root modules can have configuration_aliases = [ restapi.main ] ?
  2. it has something like:
module "create_bucket" {
  providers = {
    # child module provider name = root module provider name you are passing 
    restapi.main                 = restapi.main
  }  
  source = "./modules/create_bucket"
}
So, the short version: the left-hand side is the provider name in the child module (i.e., the module you are calling) while the right-hand side is the provider configuration in the root module (i.e., the module you are calling the child module from). This way you are assigning the root module provider configuration to the child module provider configuration. 

But I think the left is the provider name in the root module, and the right is the alias name in the child because of polymophism. So, my understanding is opposite to the post. I might be wrong. In the documenation, it says:

The value of providers is a map, where:

  • The keys are the provider configuration names used inside the child module.
  • The values are provider configuration names from the parent module.

Could you help me better understand this?

  1. I read the documentation. my question is, when should I define provider in child module? When to use alias in module and resource creation? Alias seems is used differently in module and resource creation.

Hi @wshao12,

Each module has a completely separate namespace for provider configurations.

In your root module you declare the provider configuration itself, causing the provider to be instantiated:

terraform {
  required_providers = {
    restapi = {
       # (I'm guessing you're intending to use this provider.)
      source = "mastercard/restapi"
    }
  }
}

provider "restapi" {
  alias = "main"
  # ...
}

The root module should not use configuration_aliases, because this module is defining its own restapi.main, rather than having it passed in from its parent module. (A root module does not have a parent module, so it cannot have providers passed in from outside.)

Your child module should declare that it requires an instance of this provider to be passed in by its caller.

It’s acceptable to use the same alias name in the child module if you wish, but that’s not required. It’s often better to use an alias name that makes sense for how the child module will use the provider, regardless of how the root module named it. To make it clearer which namespace is which I’m going to use the alias foo in the child module, to distinguish it from the root module’s main, but you can keep it called main in your real module if you like.

Example child module:

terraform {
  required_providers = {
    restapi = {
      source = "mastercard/restapi"
      configuration_aliases = [
        aws.foo,
      ]
    }
  }
}

# NOTE: No provider "restapi" block here.

The above declaration states that any module that calls this module must use the providers argument to pass an existing provider instance into that slot:

module "bucket" {
  source = "./modules/bucket"
  providers = {
    restapi.foo = restapi.main
  }

  # ...
}

The above example means: whenever this module refers to restapi.foo in its own namespace, use the configuration that’s called restapi.main in this namespace.