github.com/hugorut/terraform@v1.1.3/website/docs/language/functions/flatten.mdx (about) 1 --- 2 page_title: flatten - Functions - Configuration Language 3 description: The flatten function eliminates nested lists from a list. 4 --- 5 6 # `flatten` Function 7 8 `flatten` takes a list and replaces any elements that are lists with a 9 flattened sequence of the list contents. 10 11 ## Examples 12 13 ``` 14 > flatten([["a", "b"], [], ["c"]]) 15 ["a", "b", "c"] 16 ``` 17 18 If any of the nested lists also contain directly-nested lists, these too are 19 flattened recursively: 20 21 ``` 22 > flatten([[["a", "b"], []], ["c"]]) 23 ["a", "b", "c"] 24 ``` 25 26 Indirectly-nested lists, such as those in maps, are _not_ flattened. 27 28 ## Flattening nested structures for `for_each` 29 30 The 31 [resource `for_each`](/language/meta-arguments/for_each) 32 and 33 [`dynamic` block](/language/expressions/dynamic-blocks) 34 language features both require a collection value that has one element for 35 each repetition. 36 37 Sometimes your input data structure isn't naturally in a suitable shape for 38 use in a `for_each` argument, and `flatten` can be a useful helper function 39 when reducing a nested data structure into a flat one. 40 41 For example, consider a module that declares a variable like the following: 42 43 ```hcl 44 variable "networks" { 45 type = map(object({ 46 cidr_block = string 47 subnets = map(object({ cidr_block = string })) 48 })) 49 } 50 ``` 51 52 The above is a reasonable way to model objects that naturally form a tree, 53 such as top-level networks and their subnets. The repetition for the top-level 54 networks can use this variable directly, because it's already in a form 55 where the resulting instances match one-to-one with map elements: 56 57 ```hcl 58 resource "aws_vpc" "example" { 59 for_each = var.networks 60 61 cidr_block = each.value.cidr_block 62 } 63 ``` 64 65 However, in order to declare all of the _subnets_ with a single `resource` 66 block, we must first flatten the structure to produce a collection where each 67 top-level element represents a single subnet: 68 69 ```hcl 70 locals { 71 # flatten ensures that this local value is a flat list of objects, rather 72 # than a list of lists of objects. 73 network_subnets = flatten([ 74 for network_key, network in var.networks : [ 75 for subnet_key, subnet in network.subnets : { 76 network_key = network_key 77 subnet_key = subnet_key 78 network_id = aws_vpc.example[network_key].id 79 cidr_block = subnet.cidr_block 80 } 81 ] 82 ]) 83 } 84 85 resource "aws_subnet" "example" { 86 # local.network_subnets is a list, so we must now project it into a map 87 # where each key is unique. We'll combine the network and subnet keys to 88 # produce a single unique key per instance. 89 for_each = { 90 for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet 91 } 92 93 vpc_id = each.value.network_id 94 availability_zone = each.value.subnet_key 95 cidr_block = each.value.cidr_block 96 } 97 ``` 98 99 The above results in one subnet instance per subnet object, while retaining 100 the associations between the subnets and their containing networks. 101 102 ## Related Functions 103 104 * [`setproduct`](/language/functions/setproduct) finds all of the combinations of multiple 105 lists or sets of values, which can also be useful when preparing collections 106 for use with `for_each` constructs.