Terraform:通过地图进行交互并访问子值

Terraform:通过地图进行交互并访问子值

我有一个如下定义的 terraform 变量:

variable "domains" {
  default = {
    instance01 = [
      "example.com",
      "www.example.com",
      "staging.example.com"
    ]
  }
}

Terraform 版本: Terraform v0.13.3

我如何访问域名instance01并循环遍历值?

我如何访问实例名称并循环遍历实例名称?

编辑:

我尝试创建一个循环来迭代每个实例以及与该实例关联的列表中的每个域名:

resource "aws_lb_listener_certificate" "lb_listener_certs" {
  for_each        = var.domains
  listener_arn    = aws_lb_listener.front_end_https[each.key].arn
  certificate_arn = data.aws_acm_certificate.cert[each.value].arn
}

我得到的错误是:

Error: Invalid index

  on main.tf line 86, in resource "aws_lb_listener_certificate" "lb_listener_certs":
  86:   certificate_arn = data.aws_acm_certificate.cert[each.value].arn
    |----------------
    | data.aws_acm_certificate.cert is object with 3 attributes
    | each.value is tuple with 3 elements

The given key does not identify an element in this collection value: string
required.

它应该为每个键(例如 instance01)和列表 a 的每个子项aws_lb_listener_certificate(例如example.comwww.example.com)创建。但我无法让它对分配给 的列表项进行迭代instance01

我基本上想让它制作一张这样的地图:

instance01 => example.com
instance01 => www.example.com
instance01 => staging.example.com

我想使用这个键值对来创建aws_lb_listener_certificate

答案1

要获取域列表,请使用var.domains.instance01。这是域的列表。

在 Terraform 中,迭代可能意味着多种含义。如果要转换列表(例如将其转换为大写),请使用 for 表达式val = [for domain in var.domains.instance01: upper(domain)]::

[
  "EXAMPLE.COM",
  "WWW.EXAMPLE.COM",
  "STAGING.EXAMPLE.COM",
]

如果您想要为实例的每个域获取资源,则可以使用for_each

resource "res" "r" {
  for_each = var.domains.instance01
  domain = each.key
}

(参考:https://www.terraform.io/docs/configuration/resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings

要获取实例名称,可以使用以下key函数:

keys(var.domains)
[
  "instance01",
]

答案2

好的,我认为我找到了解决方案:

variable "domains" {
  default = {
    instance01 = [
      "example.com",
      "www.example.com",
      "staging.example.com"
    ]
  }
}

locals {
  domain-association-list = flatten([
    for instance, domains in var.domains : [
      for domain in domains : {
        instance = instance
        domain = domain
      }
    ]
  ])

  domain-association-map = { for item in local.domain-association-list: 
     values(item)[0] => values(item)[1]
   }
}

resource "aws_lb_listener_certificate" "lb_listener_certs" {
  for_each        = local.domain-association-map
  listener_arn    = aws_lb_listener.front_end_https[each.value].arn
  certificate_arn = data.aws_acm_certificate.cert[each.key].arn
}

相关内容