Skip to content
Branch: master
Find file History
Latest commit 04c934d Mar 16, 2019
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
README.md split out README.md Mar 16, 2019
main.tf added dynamic blocks Mar 16, 2019

README.md

Dynamic Blocks and Splat Expressions Example

The Dynamic Blocks and Splat Expresions example shows how the dynamic blocks can be used to dynamically create multiple instances of a block within a resource and how splat expressions ([*]) can now be used to iterate across those blocks. Recall that the old splat expression (.*) could only iterate across top-level attributes of a resource.

In this example, we create an AWS security group with 2 dynamically generated ingress blocks and then create an output that iterates across the ingress blocks to give us both ports.

Here is the variable with the list of ports for the ingress rules:

variable "ingress_ports" {
  type        = list(number)
  description = "list of ingress ports"
  default     = [8200, 8201]
}

Note that we have explicitly declared the variable to have type list(number). This was not necessary, but it illustrates the expanded types available within Terraform 0.12.

Here is the aws_security_group resource:

resource "aws_security_group" "vault" {
  name        = "vault"
  description = "Ingress for Vault"
  vpc_id      = aws_vpc.my_vpc.id

  dynamic "ingress" {
    iterator = port
    for_each = var.ingress_ports
    content {
      from_port   = port.value
      to_port     = port.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}

Instead of declaring two separate ingress blocks, we declared a single dynamic ingress block. We also specified the iterator argument as port. (Don't use quotes.) If we had not done that, then we would have used ingress.value instead of port.value in the code since the default iterator is the label of the dynamic block.

The repetition of dynamic blocks is generated from the for_each argument which say what variable to iterate over. The referenced variable should be a list or a map. For lists, you can refer to the "value" of each member. For maps, you can refer to the "key" and "value" of each member. The actual repeated block is generated from the nested content block.

Here is the output which uses the new splat expression:

output "ports" {
  value = aws_security_group.vault.ingress[*].from_port
  #value = aws_security_group.vault.ingress.*.from_port
}

Note that the splat expression occurs after "ingress" and that we used the new version [*] instead of the old version .* which we show in a comment. You can use either version in Terraform 0.12, but neither would have worked in older versions for nested blocks.

The actual output generated by the apply is:

from_ports = [
  8201,
  8200,
]
You can’t perform that action at this time.