4

I'm creating a terraform module which is working fine. However, when I use it multiple times it creates multiples roles and policies which are literally the same.

I'm thinking if there is a way for the module to create a role when I call it for the first time and keep using the same role for the subsequent modules

DevOpsNRZ
  • 132
  • 1
  • 8
  • No, that is not how this works in general. You *can* implement this yourself by adding an input variable to the module and depending on the variable use the role it points to or create one if the variable is empty and then output the role. – luk2302 Jul 15 '21 at 13:13

1 Answers1

10

No, Terraform does not support this. Your best bet is to create the shared resources outside the module (or in a separate module), and then pass them in as input arguments into the module you're creating multiple times.

I like the approach of having a module for "shared" resources, because then you can pass that entire module in as an input argument into any module that uses those shared resources.

EDIT: Sample code for shared modules:

main.tf

module "mod1" {
  source = "./mymodule1"
}

module "mod2" {
  source       = "./mymodule2"
  input_module = module.mod1
}

output "mod2" {
  value = module.mod2
}

mymodule1/main.tf

output "some_field" {
  value = "foo"
}

mymodule2/main.tf

variable "input_module" {}

output "module_that_was_input" {
  value = var.input_module
}

Result:

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

mod2 = {
  "module_that_was_input" = {
    "some_field" = "foo"
  }
}
Jordan
  • 3,998
  • 9
  • 45
  • 81
  • Does passing the "shared" module into other modules actually work? When I just tried it, it wouldn't let me pass whole objects. I had to export specific values. e.g. I have a AWS ACM Certificate I wanted to share between multiple other modules. Terraform wouldn't let me pass the shared module in. Instead I had to export the ACM ARN as an output variable, and input that same variable into the other module. Would be keen to see an example of passing the entire module in that you mentioned. – Kieran Pilkington Jul 21 '21 at 04:04
  • It does work (at least with TF v1.0.1, which I'm currently testing with). See my updated answer for sample code. – Jordan Jul 21 '21 at 19:24
  • Thanks for the code samples Jordan. The above worked. The confusion was in me trying to access resources through the shared module (input_module.aws_acm_certificate.main.arn), when it appears to only import module1's output variables when passing in the module to module2. – Kieran Pilkington Jul 25 '21 at 21:46
  • Glad it worked! Yes, it's always true that you can only access things created in a module if they are "output". If this solves your problem, please accept the answer so the question is marked as closed. – Jordan Jul 26 '21 at 01:13