从 Terraform 地图变量中提取值

Extract Values from terraform map variable

我正在尝试根据以下特定条件从地图变量中提取值:-

    Variables.tf File content
    variable "users" {
    type = "map"
    default = {
    "101" = "abc@gmail.com"
    "102" = "def@gmail.com"
    "103" = "xyz@gmail.com"
    "104" = "klm@gmail.com"
    "105" = "pqr@gmail.com"
    "106" = "tuv@gmail.com"
     }
   }

下面是我的main.tf文件

    module "instance" {
    instance_private_ip = ["11.12.13.x"]
    dns_map = ["y"]
    users = ["z"]
    }

    module "instance2" {
    instance_private_ip = ["11.12.14.a"]
    dns_map = ["b"]
    users = ["c"]
    }

x 应该是用户变量中的所有偶数,例如 - 102、104 等等。y 应与 x 相同 值 z 应该对应于 x 和 y。 值 a 应该是用户变量中的所有偶数,例如 - 101、103 等等。b 应与 a 相同 值c应该对应a和b。例子如下

module "instance" {
    instance_private_ip = ["11.12.13.102", "11.12.13.104", "11.12.13.106"]
    dns_map = ["102","104","106"]
    users = ["def@gmail.com","klm@gmail.com","tuv@gmail.com"]
    }
module "instance2" {
    instance_private_ip = ["11.12.14.101", "11.12.14.103", "11.12.14.105"]
    dns_map = ["101","103","105"]
    users = ["abc@gmail.com","xyz@gmail.com","pqr@gmail.com"]
    }

我正在尝试使用 ${element(var.notebook[count.index])} 但它会给我用户名而不是左侧变量。

感谢任何帮助

Terraform 的 for expressions 是大多数涉及集合转换和过滤的问题的答案,我认为这个案例也是如此。

locals {
  odd_users = [
    for octet, email in var.users : {
      email               = email
      octet               = octet
      dns_map             = tostring(octet)
      instance_private_ip = cidrsubnet("11.12.14.0/24", octet)
    }
    if (octet % 2) == 1
  ]
  even_users = [
    for octet, email in var.users : {
      email               = email
      octet               = octet
      dns_map             = tostring(octet)
      instance_private_ip = cidrsubnet("11.12.13.0/24", octet)
    }
    if (octet % 2) == 0
  ]
}

module "instance" {
  source = "..."

  instance_private_ip = local.even_users[*].instance_private_ip
  dns_map             = local.even_users[*].dns_map
  users               = local.even_users[*].email
}

module "instance2" {
  source = "..."

  instance_private_ip = local.odd_users[*].instance_private_ip
  dns_map             = local.odd_users[*].dns_map
  users               = local.odd_users[*].email
}

在上面的例子中,两个局部值首先过滤和转换列表,每个产生一个描述用户的对象列表。然后在两个 module 块中,我使用 splat expressions 将其转换回您在示例中所要求的平面字符串列表,


与其在子模块中定义三个必须具有相同长度和索引的单独变量,我建议重新设计该接口以获取单个对象列表。您可以像这样在子模块中定义一个变量 users

variable "users" {
  type = list(object({
    email               = string
    dns_map             = string
    instance_private_ip = string
  }))
}

有了这样的定义,您可以直接在模块调用中传递本地值:

module "instance" {
  source = "..."

  users = local.even_users
}

module "instance2" {
  source = "..."

  users = local.odd_users
}

如果需要,您的子模块本身可能会使用 splat 表达式再次获取字符串的平面列表,或者它可以直接使用对象列表,具体取决于子模块将对这些列表执行的操作.