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