Passing modules in a list as an input

Hi,

Im trying to pass a modules list into another module, for some unknown reason - when sending 2 modules it works properly but for > 2 it troughs an error -
all list elements must have the same type.

module "D" {
  modules = ["${module.A}","${module.B}","${module.C}"]
}

Please advice on how to overcome this issue.

Thanks,

Hi,

This is likely due to the fact that the outputs and their types from modules A-C are not identical and feeding into the modules variable of module D which has a type=list(any) or similar using any

check the documentation which explains the rules and assumptions that Terraform operates under when using the ‘any’ keyword Type Constraints - Configuration Language | Terraform | HashiCorp Developer which states:

The keyword any is a special construct that serves as a placeholder for a type yet to be decided. any is not itself a type: when interpreting a value against a type constraint containing any , Terraform will attempt to find a single actual type that could replace the any keyword to produce a valid result.

additionally, when using ‘any’ with a collection type:

All of the elements of a collection must have the same type, so if you use any as the placeholder for the element type of a collection then Terraform will attempt to find a single exact element type to use for the resulting collection.

Here is a contrived example using very simplified code to reproduce your error:

Module A (main.tf):

output "module_A_output" {
  value = "A"
}

Module B (main.tf):

output "module_B_output" {
  value = "B"
}

Module C (main.tf):

output "module_C_output" {
  value = [3]
}

Module D (main.tf):

variable "modules_in" {
  type = list(any)
}

‘Root’ Module (main.tf):

module "a" {
  source = "./modules/a"
}

module "b" {
  source = "./modules/b"
}

module "c" {
  source = "./modules/c"
}

module "d" {
  source = "./modules/d"
  modules_in = [
    "${module.a}",
    "${module.b}",
    "${module.c}"
  ]
}

The above will error with:

The given value is not suitable for module.d.var.modules_in declared at modules\d\main.tf:1,1-22: all list elements must have the same type.

Because the outputs of modules A & B are simple strings, whereas the output of module C is a list of number.

Terraform will try and implicitly convert between datatypes where possible, so if the output of module C was a number (not a list), then it would implicitly convert to a string. However it will not/cannot implicitly convert a list of strings to a string and therefore cannot find a single type (or collection) that will ‘fit’ the outputs of all three modules during the ‘input’ to the variable for module D.

You need to ensure that your outputs of the modules you are providing in the list to D are the same, be they simple output values or more complex output values using collections in which the structure and types of the elements in the collection also need to match, between the modules that are being used in the list, into the receiving module.

Hope that helps

Happy Terraforming!