从 terraform 地图变量中提取值

Arp*_*pta 7 terraform terraform-provider-aws

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

    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"
     }
   }
Run Code Online (Sandbox Code Playgroud)

下面是我的 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"]
    }
Run Code Online (Sandbox Code Playgroud)

用户变量中的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"]
    }
Run Code Online (Sandbox Code Playgroud)

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

任何帮助表示赞赏

Mar*_*ins 9

Terraform 的for表达式可以解决大多数涉及集合转换和过滤的问题,我认为这种情况也是如此。

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
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,两个本地值首先过滤并转换列表,每个值都会生成一个描述用户的对象列表。然后在这两个module块中,我使用splat 表达式将其转换回您在示例中所要求的平面字符串列表,


我建议重新设计该接口以采用单个对象列表,而不是在子模块中定义三个必须具有相同长度和索引的单独变量。您可以users在子模块中定义一个变量,如下所示:

variable "users" {
  type = list(object({
    email               = string
    dns_map             = string
    instance_private_ip = string
  }))
}
Run Code Online (Sandbox Code Playgroud)

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

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

  users = local.even_users
}

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

  users = local.odd_users
}
Run Code Online (Sandbox Code Playgroud)

然后,您的子模块本身可能会使用 splat 表达式再次获取字符串的平面列表(如果这是它需要的),或者它可以直接使用对象列表,具体取决于子模块将如何处理这些列表。