从Terraform地图变量中提取值

时间:2020-01-23 09:12:23

标签: terraform terraform-provider-aws

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

    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])}},但是它将为我提供用户名,而不是左侧变量。

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

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表达式再次获取平面的字符串列表(如果需要的话),或者它可以直接使用对象列表,具体取决于子模块将对这些列表进行处理。 / p>