Reputation: 57
I need to get the terraform parent module name from the path and then pass it as a variable to other module. Is it possible?. Example: From the module child1, it can access to the directory src/yaml in the module child2
module "parent" {
source = "s3::https://s3.amazonaws.com/tf-modules-zip/child1.zip"
some_variable = "foo"
}
variable "some_variable" {
type = string
description = "Any value"
}
locals {
os_module_name = this.module.name
path_to_yamls = "${local.os_module_name}.child2/src/yaml"
}
module "child1" {
source = "s3::https://s3.amazonaws.com/tf-modules-zip/child2.zip"
some_variable = var.some_variable
path_to_yaml_files = local.path_to_yamls
}
variable "some_variable" {
type = string
description = "Any value"
}
variable "path_to_yaml_files" {
type = string
description = "Path to retrieve the yaml files"
}
locals {
path_to_configs = var.path_to_yaml_files
exclusions = yamldecode(file("${local.path_to_configs}/exclusions.yaml"))
}
resource "null_resource" "child2" {
local-exec {
interpreter = ["/bin/bash" ,"-c"],
command = <<-EOT
exec "command1 -yaml ${local.exclusions}"
exec "command2 -var ${var.some_variable}"
EOT
}
}
Upvotes: 0
Views: 2281
Reputation: 57
Yes, It's possible!. Just using the module path to extract the parent portion and then concatenate it to the child1 path.
main.tf
module "parent" {
source = "s3::https://s3.amazonaws.com/tf-modules-zip/child1.zip" # <-- Calling the child1 module
some_variable = "foo" # <-- Assigning the foo value to some_variable
}
child1.tf
variable "some_variable" { # <-- Input variable
type = string
description = "Any value"
}
locals {
parent_module_name = path.module != "." ? regex(".*/([^/]+)?", path.module)[0] : "." ### <-- Extracting the parent module name from the current module path
path_to_yamls = "${path.module}/../${local.parent_module_name}.child1/src/yaml" ### <-- Concatenating the parent module name with the child2 module path
}
module "child1" {
source = "s3::https://s3.amazonaws.com/tf-modules-zip/child2.zip" # <-- Calling the child2 module
some_variable = var.some_variable # <-- Injecting the value of var.some_variable to the child2 module
path_to_yaml_files = local.path_to_yamls # <-- Injecting the value of local.path_to_yamls to the child2 module
}
child2.tf
variable "some_variable" { # <-- Input variable
type = string
description = "Any value"
}
variable "path_to_yaml_files" { # <-- Input variable
type = string
description = "Path to retrieve the yaml files"
}
locals {
path_to_configs = var.path_to_yaml_files # <-- Using the injected value in var.path_to_yaml_files from the child1 module
exclusions = yamldecode(file("${local.path_to_configs}/exclusions.yaml")) # <-- Using the injected value in var.path_to_yaml_files from the child1 module
}
resource "null_resource" "child2" {
local-exec {
interpreter = ["/bin/bash" ,"-c"],
command = <<-EOT
exec "command1 -yaml ${local.exclusions}" # <-- Using the injected value in var.path_to_yaml_files from the child1 module
exec "command2 -var ${var.some_variable}" # <-- Using the injected value in var.path_to_yaml_files from the child1 module
EOT
}
}
When we do a "terraform init", the modules are downloaded in the parent path under this structure:
-[example]
main.tf
|--[.terraform]
|--[modules]
|--[parent]
child1.tf
|--[parent.child1]
child2.tf
|--[src]
|--[yaml]
file1.yaml
file2.yaml
file3.yaml
Usig the "path.module" do the trick. It gets the module path from it's called. In this example, it's being called from child1 which has the name "parent". Then, the expression: "${path.module}/../${local.parent_module_name}.child1/src/yaml" tells to terraform that it has to go up a level and then go to the "parent.child1/src/yaml" directory after the interpolation of the "${local.parent_module_name}" variable which has the value "parent".
The advantage of this method is that the parent module name can be changed in the main.tf file and afer to do a "terraform init -upgrade", the directory structure takes the new value.
I hope this helps a lot!.
Upvotes: 2