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