Terraform 的 for_each 中的迭代器功能是什么?

Ale*_*vey 5 terraform

我想了解iterator的功能for_each在Terraform 0.12。该文件说:

迭代器:

iterator参数(可选)设置表示复值的当前元素的临时变量的名称。如果省略,变量名默认为动态块的标签...

但是我找不到任何使用此功能的代码示例,而且我无法理解它的用途。我已经阅读了 Terraform 0.12预览版,但那里没有提到它,我发现了一些 GitHub 问题(例如这个),但也找不到线索。

仅仅是为了提高可读性吗?我真的很感激一个代码示例和解释,它超出了我在文档中所能找到的范围。

Mat*_*ard 8

基本上在 Python、Ruby、C++、Javascript、Groovy 等各种语言中,您可以在 lambda 中建立一个临时变量(尤其是迭代时),用于在 lambda 中存储每次迭代的临时值。在某些语言(例如 Groovy)中,该变量有一个默认名称,或者您可以自己设置一个(即 Groovy 中的默认变量名称是it)。例如,在 Groovy 中,我们有:

strings.each() {
  print it
}
Run Code Online (Sandbox Code Playgroud)

将打印string变量赋值的内容(假设它可以转换为字符串)。以下代码具有完全相同的功能:

strings.each() { a_string ->
  print a_string
}
Run Code Online (Sandbox Code Playgroud)

我们已经明确地将临时变量命名为a_string. 这类似于iterator您问题中的论点。所以在 Terraform 中,我们在文档中看到了一个例子:

resource "aws_security_group" "example" {
  name = "example" # can use expressions here

  dynamic "ingress" {
    for_each = var.service_ports
    content {
      from_port = ingress.value
      to_port   = ingress.value
      protocol  = "tcp"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

根据文档:

如果省略,变量名默认为动态块的标签

上面的名称是ingress(注意它是在dynamic块旁边指定的标签)。果然,我们看到上面的临时变量的名字是ingress,它是通过ingress.value. 要利用iterator重命名此临时变量的功能,我们可以执行以下操作。

resource "aws_security_group" "example" {
  name = "example" # can use expressions here

  dynamic "ingress" {
    for_each = var.service_ports
    iterator = "service_port"
    content {
      from_port = service_port.value
      to_port   = service_port.value
      protocol  = "tcp"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

因此将var.service_portslambda 内每次迭代中存储元素的临时变量从默认名称重命名ingressservice_port。我在这方面看到的主要附加值(同样当我在 Groovy 中为 Jenkins Pipeline 库使用它时)是为存储值的临时变量提供更清晰的名称以提高可读性。