Problem
A user may run into the following error during the initialization of a configuration:
│ Error: Module is incompatible with count, for_each, and depends_on
│
│ on main.tf line 11, in module "test":
│ 11: count = 2
│
│ The module at module.test is a legacy module which contains its own local provider configurations, and so calls to it may not use the count, for_each, or
│ depends_on arguments.
│
│ If you also control the module "./test", consider updating this module to instead expect provider configurations to be passed by its caller.
Cause
Modules which contain their own local provider configuration are considered legacy modules. Legacy modules may not use the count, for_each, or depends_on arguments. This error is occurring because a count, for_each, or depends_on is being used in conjunction with a legacy module.
Overview of Possible Solutions
Depending on the scenario, there may be different possible solutions. If all resources in the child module need to use the same provider configuration per invocation, then use Possible Solution #1. If different resources in the child module need to use different provider configurations, then use Possible Solution #2.
Possible Solution #1
- Refactor the configuration to remove the count, for_each, or depends_on. If using a count or for_each, use multiple module invocation blocks instead.
Original Configuration
main.tf
variable "azure_credentials" {
type = map(map(string))
default = {
sp1 = {
client_id = "<some_client_id>",
client_secret = "<some_client_secret>",
subscription_id = "<some_subscription_id>"
},
sp2 = {
client_id = "<another_client_id>",
client_secret = "<another_client_secret>",
subscription_id = "<another_subscription_id>"
}
}
}
module "test" {
source = "./test"
for_each = var.azure_credentials
client_id = each.value.client_id
client_secret = each.value.client_secret
subscription_id = each.value.subscription_id
}
./test/main.tf
provider "azurerm" {
client_id = var.client_id
client_secret = var.client_secret
subscription_id = var.subscription_id
features {}
}
variable "client_id" {}
variable "client_secret" {}
variable "subscription_id" {}
resource "random_pet" "resource_group_suffix" {
length = 2
}
resource "azurerm_resource_group" "test" {
name = random_pet.resource_group_suffix.id
location = "East US"
}
Refactored Configuration
main.tf
variable "azure_credentials" {
type = map(map(string))
default = {
sp1 = {
client_id = "<some client_id>",
client_secret = "<some_client_secret>",
subscription_id = "<some_subscription_id>"
},
sp2 = {
client_id = "<another_client_id>",
client_secret = "<another_client_secret>",
subscription_id = "<another_subscription_id>"
}
}
}
module "test" {
source = "./test"
client_id = var.azure_credentials["sp1"].client_id
client_secret = var.azure_credentials["sp1"].client_secret
subscription_id = var.azure_credentials["sp1"].subscription_id
}
module "test2" {
source = "./test"
client_id = var.azure_credentials["sp2"].client_id
client_secret = var.azure_credentials["sp2"].client_secret
subscription_id = var.azure_credentials["sp2"].subscription_id
}
Possible Solution #2
- Refactor the configuration to remove the provider configuration from the module source code and instead pass it into the child module from the root module.
Original Configuration
main.tf
variable "primary_subscription_id" {}
variable "dr_subscription_id" {}
module "test" {
source = "./test"
count = 2
primary_subscription_id = var.primary_subscription_id
dr_subscription_id = var.dr_subscription_id
}
./test/main.tf
provider "azurerm" {
alias = "primary"
subscription_id = var.primary_subscription_id
features {}
}
provider "azurerm" {
alias = "dr"
subscription_id = var.dr_subscription_id
features {}
}
variable "primary_subscription_id" {}
variable "dr_subscription_id" {}
resource "random_pet" "resource_group_suffix" {
length = 2
}
resource "azurerm_resource_group" "primary" {
provider = azurerm.primary
name = random_pet.resource_group_suffix.id
location = "East US"
}
resource "azurerm_resource_group" "dr" {
provider = azurerm.dr
name = random_pet.resource_group_suffix.id
location = "East US"
}
Refactored configuration
main.tf
provider "azurerm" {
alias = "primary"
subscription_id = var.primary_subscription_id
features {}
}
provider "azurerm" {
alias = "dr"
subscription_id = var.dr_subscription_id
features {}
}
variable "primary_subscription_id" {}
variable "dr_subscription_id" {}
module "test" {
source = "./test"
count = 2
providers = {
azurerm.primary = azurerm.primary
azurerm.dr = azurerm.dr
}
}
./test/main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
configuration_aliases = [ azurerm.primary, azurerm.dr ]
}
}
}
resource "random_pet" "resource_group_suffix" {
length = 2
}
resource "azurerm_resource_group" "primary" {
provider = azurerm.primary
name = random_pet.resource_group_suffix.id
location = "East US"
}
resource "azurerm_resource_group" "dr" {
provider = azurerm.dr
name = random_pet.resource_group_suffix.id
location = "East US"
}
Outcome
After refactoring the configuration, Terraform should no longer run into this error.
Additional Information
If the above solution does not resolve your issue, please open a ticket with HashiCorp Support for additional assistance.