首页 > 解决方案 > Terraform:获取模块名称以将其从路径注入到其他模块

问题描述

我需要从路径中获取 terraform 父模块名称,然后将其作为变量传递给其他模块。可能吗?。示例:从模块child1,可以访问模块child2中的目录src/yaml

父模块:

module "parent" {
  source = "s3::https://s3.amazonaws.com/tf-modules-zip/child1.zip"
  some_variable = "foo"
}

Child1 模块:

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
}

Child2 模块:

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
  }
}

标签: terraformterraform0.12+terraform-modules

解决方案


是的,这是可能的!只需使用模块路径提取父部分,然后将其连接到 child1 路径。

回答

父模块:

主文件

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 模块:

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 模块:

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
  }
}

解释:

当我们执行“terraform init”时,模块会下载到此结构下的父路径中:

-[example]
   main.tf
 |--[.terraform]
    |--[modules]
       |--[parent]
            child1.tf
       |--[parent.child1]
            child2.tf
          |--[src]
             |--[yaml]
                  file1.yaml
                  file2.yaml
                  file3.yaml

使用“path.module”就可以了。它从中获取模块路径。在此示例中,它是从名为“parent”的 child1 调用的。然后,表达式: "${path.module}/../${local.parent_module_name}.child1/src/yaml" 告诉 terraform 它必须上升一个级别,然后转到 "parent.child1/在“${local.parent_module_name}”变量的插值之后的 src/yaml”目录,该变量的值为“parent”。

这种方法的优点是可以在 main.tf 文件中更改父模块名称,然后执行“terraform init -upgrade”,目录结构采用新值。

我希望这有很大帮助!


推荐阅读