How to specify multiple variants of the same provider in a module’s required_providers section

I’m trying to author a Terraform module that will be able to manage resources in two different “configurations” of the same provider but am unable to declare those configurations in the required_providers block.

This leads to the message:

Provider hashicorp/azurerm with the local name “az” was previously required as “log”. A provider can only be required once within required_providers.

E.g. Extract from sample code available:

main.tf

terraform {
	backend "azurerm" {}
}

provider "azurerm" {
    features              {}
    alias                     = "az"
    subscription_id  = var.subscription_id
    tenant_id            = var.tenant_id
}

provider "azurerm" {
    features              {}
    alias                     = "log"
    subscription_id  = var.subscription_id
    tenant_id            = var.tenant_id
}

resource "azurerm_resource_group" "main" {
	name     = "rg-main"
	location = "West Europe"
	provider = azurerm.az
}

module "module" {
	source = "./modules/module"
	providers = {
		az = azurerm.az
		log = azurerm.log
	}
}

./modules/module/main.tf

terraform {
	required_providers {
		az = { source = "hashicorp/azurerm" }
		log = { source = "hashicorp/azurerm" }
	}
}

Hi @springcomp,

A provider configuration address contains either one or two parts. A single-part address like azurerm represents the default (unaliased) configuration for whatever provider you’ve named “azurerm”, while a two-part address like azurerm.foo represents an additional (aliased) configuration for that same provider, where the alias is “foo”.

Your child module is declaring two different local names for the same provider, which is incorrect. I think instead you want to declare two configurations for the same provider, which you can do using the following structure:

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      configuration_aliases = [ azurerm, azurerm.log ]
    }
}

This declares that the module needs two configurations for this provider: one default configuration and one additional configuration with the alias “log”.

You can then explain to Terraform in the module block how to associate the provider configurations in your root module with the ones in the child module:

  providers = {
    azurerm = azurerm.az
    azurerm.log = azurerm.log
  }

The configuration addresses on the left side of these assignments must match the “configuration aliases” declared inside the module, and the ones on the right must each match one of the configurations declared in the root module.

That definitely answers my question.
Thanks a lot for your feedback.