Terraform Iterators
Using for_each on a list of strings:
1 2 3 4 5 6 7 8
locals { ip_addresses = ["10.0.0.1", "10.0.0.2"] } resource "example" "example" { for_each = toset(local.ip_addresses) ip_address = each.key }
Using for_each on a list of objects
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
locals { virtual_machines = [ { ip_address = "10.0.0.1" name = "vm-1" }, { ip_address = "10.0.0.1" name = "vm-2" } ] } resource "example" "example" { for_each = { for index, vm in local.virtual_machines: vm.name => vm } name = each.value.name ip_address = each.value.ip_address }
Using for_each to combine two lists
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
locals { domains = [ "https://abc.com", "https://def.com" ] paths = [ "/one", "/two", "/three" ] } resource "example" "example" { # Loop over both lists and flatten the result urls = flatten([ for domain in local.domains : [ for path in local.paths : { domain = domain path = path } ] ]) }
Using for_each on a nested block
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
# Using the optional() keyword makes fields null if not present variable "routes" { type = list( name = string path = string config = optional(object({ cache_enabled = bool https_only = bool })) default = [] } resource "example" "example" { name = ... dynamic "route" { for_each = { for route in var.routes : route.name => route } content { # Note: <top_level_block>.value.<object_key> name = route.value.name } dynamic "configuration" { # Note: <top_level_block>.value.<optional_object_key> for_each = route.value.config != null ? [1] : [] content { cache_enabled = route.value.config.cache_enabled https_only = route.value.config.https_only } } }
Using for_each as a conditional
``` variable “deploy_example” { type = bool description = “Indicates whether to deploy something.” default = true }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Using count and a conditional, for_each is also possible here.
# See the next solution using a for_each with a conditional.
resource "example" "example" {
count = var.deploy_example ? 0 : 1
name = ...
ip_address = ...
}
variable "enable_logs" {
type = bool
description = "Indicates whether to enable something."
default = false
}
resource "example" "example" {
name = ...
ip_address = ...
# Note: dynamic blocks cannot use count!
# Using for_each with an empty list and list(1) as a readable alternative.
dynamic "logs" {
for_each = var.enable_logs ? [] : [1]
content {
name = "logging"
}
}
}
```
This post is licensed under CC BY 4.0 by the author.