I am trying to understand the iterator
feature of the for_each
in Terraform 0.12. The docs say:
Iterator:
The
iterator
argument (optional) sets the name of a temporary variable that represents the current element of the complex value. If omitted, the name of the variable defaults to the label of the dynamic block ...
But I can't find any code examples that uses this feature and I can't get my head around what it is for. I have read the Terraform 0.12 preview but it is not mentioned there, and I found some GitHub issues (e.g. this one) but can't find clues there either.
Is it just for improving readability? I would really appreciate a code example and explanation that goes beyond what I can find in the docs.
Basically in various languages like Python, Ruby, C++, Javascript, Groovy, etc. you can establish a temporary variable within a lambda (especially if it is iterative) that stores the temporary value per iteration within the lambda. In some languages (e.g. Groovy), there is a default name for this variable, or you can set one yourself (i.e. default variable name in Groovy is it
). For example, in Groovy we have:
strings.each() {
print it
}
would print the content of the string
variable assignment (assuming it can be cast to String). The following code has the exact same functionality:
strings.each() { a_string ->
print a_string
}
where we have explicitly named the temporary variable as a_string
. This is analogous to the iterator
argument in your question. So in Terraform, we see an example in the documentation:
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"
}
}
}
According to the documentation:
If omitted, the name of the variable defaults to the label of the dynamic block
and the name above is ingress
(notice it is the label specified adjacent to the dynamic
block). Sure enough, we see the name of the temporary variable above is ingress
and it is being accessed via ingress.value
. To utilize the functionality of iterator
to rename this temporary variable, we can do something like the below.
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"
}
}
}
thus renaming the temporary variable storing the element of var.service_ports
in each iteration within the lambda from default name ingress
to service_port
. The primary added value I see in this (and likewise when I use it in Groovy for Jenkins Pipeline libraries) is to provide a more clear name for the temporary variable storing the value to improve readability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With