patternterraformMinor
conditionals in module providers meta-argument
Viewed 0 times
argumentconditionalsprovidersmodulemeta
Problem
I am provisioning a bunch of resources via a module.
Now, in the calling module ( the root module ), I use the alias of the provider that the child module should use. I would use the module
Now, I want to provision the same module, but based on a condition :
And I get thrown
Then I tried treating the providers meta-argument as a normal argument ( I knew it would not work, but still tried anyway ) :
This time, the error was more logical -
It does seem like the
Would there be a native way of re-using the same module declaration to switch between 2 different providers?
Or is the only way to achieve this would be code duplication and the
module "test" {
source = "../modules/my-module"
vpc_id = module.vpc.vpc_id
subnet_ids = module.subnets.ids
}Now, in the calling module ( the root module ), I use the alias of the provider that the child module should use. I would use the module
providers meta-argument :provider "my_provider" {
alias = default
region = "default"
...
}
provider "my_provider" {
alias = alias1
region = "region1"
...
}
module "test" {
source = "../modules/my-module"
providers = {
my_provider = my_provider.alias1
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.subnets.ids
}Now, I want to provision the same module, but based on a condition :
module "test" {
source = "../modules/my-module"
providers = {
my_provider = var.region == "region1" ? my_provider.alias1 : my_provider.default
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.subnets.ids
}And I get thrown
The providers argument requires a provider type name, optionally followed by a period and then a configuration alias.Then I tried treating the providers meta-argument as a normal argument ( I knew it would not work, but still tried anyway ) :
module "test" {
source = "../modules/my-module"
providers = var.region == "region1" ? { my_provider = my_provider.alias1 } : { my_provider = my_provider.default }
vpc_id = module.vpc.vpc_id
subnet_ids = module.subnets.ids
}This time, the error was more logical -
A static map expression is required.It does seem like the
providers meta-argument for modules are always supposed to be static ( essentially hard-coded ) just like the backend argument.Would there be a native way of re-using the same module declaration to switch between 2 different providers?
Or is the only way to achieve this would be code duplication and the
count meta-argument based on the condition?Solution
The relationship between a resource and its provider configuration is an important part of building the dependency graph, and Terraform must build the dependency graph before it can evaluate any expressions, so there is no way to use arbitrary expressions to describe the relationship between a resource and its provider configuration.
The
Although you cannot dynamically choose which provider configuration to assign to a resource, you can make the provider configuration itself include dynamic expressions:
In this example the module is always associated with the same provider configuration object but the arguments inside that block will vary depending on the value of
The
providers argument in a module block isn't directly specifying the relationship between the resource and its provider configuration, but it is still data used by the algorithm that ultimately resolves those connections and so it too needs to be resolved before it's possible to evaluate expressions.Although you cannot dynamically choose which provider configuration to assign to a resource, you can make the provider configuration itself include dynamic expressions:
provider "my_provider" {
alias = "for_test_module"
region = var.region == "region1" ? "region1" : "default"
}
module "test" {
source = "../modules/my-module"
providers = {
my_provider = my_provider.for_test_module
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.subnets.ids
}In this example the module is always associated with the same provider configuration object but the arguments inside that block will vary depending on the value of
var.region, thereby achieving the same effect.Code Snippets
provider "my_provider" {
alias = "for_test_module"
region = var.region == "region1" ? "region1" : "default"
}
module "test" {
source = "../modules/my-module"
providers = {
my_provider = my_provider.for_test_module
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.subnets.ids
}Context
StackExchange DevOps Q#17287, answer score: 2
Revisions (0)
No revisions yet.