0

Looked for an answer for this question in multiple posts but found solutions for a simpler scenarios only.
Let's say I have a module called a and this module depends on multiple different modules, let's call them b and c.

module "a" {
   source     = ./a
   depends_on = [module.B, module.C]
   b_id       = module.b.id
   c_id       = module.c.id
}

module "b" {
   source     = ./b
}

module "c" {
   source     = ./c
}

In the naive scenario both modules b and c will be created before we create module a, but what if I want to let the user of module a to create it's own instances of b and c and just pass their ids to a without us creating b and c.
I'm aware of the count trick on resources detailed here, but it works only for resources and not modules and to make it work here I will need to apply it to every resource inside the modules which will create a cumbersome code.
I also saw terraform conditional creation of objects but this solution works good if the main module/resource has just one conditional attribute, what if we have 10 modules that can be provisioned to us by the user or need to be created inline?

eladm26
  • 517
  • 4
  • 23
  • You could have one conditional where true evaluates to a declaration of module `b` and `c` and their outputs mapped to `a` inputs, and false evaluates to no declaration of module `b` and `c`, and `data` is mapped to `a` inputs (which would also not be declared for `true`). I can be more specific with the more specific details, or I can just write up that answer. – Matthew Schuchard Jan 31 '22 at 14:37
  • @MattSchuchard thank you for the response. what exactly do you mean with `one conditional`? – eladm26 Jan 31 '22 at 17:45

1 Answers1

1

You can use count in module blocks as long as you are using Terraform v0.13 or later:

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

   b_id = one(module.b[*].id)
   c_id = one(module.c[*].id)
}

module "b" {
   source = "./b"
   count  = 1
}

module "c" {
   source = "./c"
   count  = 0
}

The use of the one function here is to transform what would naturally be a list of either zero or one elements into a single value that may be null. Therefore your module "a" must be ready to accept null as a valid value for both b_id and c_id here, to handle the cases where there are zero instances of those modules.

Note that referring to module.b and module.c in the arguments of module "a" automatically declares dependencies on all of the outputs of those modules, and so it would be redundant to also include depends_on in the module "a" block. depends_on should be used only for "hidden dependencies", which are not reflected in the data flow between resources.

Martin Atkins
  • 62,420
  • 8
  • 120
  • 138