1--- 2layout: "language" 3page_title: "flatten - Functions - Configuration Language" 4sidebar_current: "docs-funcs-collection-flatten" 5description: |- 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 12flattened sequence of the list contents. 13 14## Examples 15 16``` 17> flatten([["a", "b"], [], ["c"]]) 18["a", "b", "c"] 19``` 20 21If any of the nested lists also contain directly-nested lists, these too are 22flattened recursively: 23 24``` 25> flatten([[["a", "b"], []], ["c"]]) 26["a", "b", "c"] 27``` 28 29Indirectly-nested lists, such as those in maps, are _not_ flattened. 30 31## Flattening nested structures for `for_each` 32 33The 34[resource `for_each`](/docs/language/meta-arguments/for_each.html) 35and 36[`dynamic` block](/docs/language/expressions/dynamic-blocks.html) 37language features both require a collection value that has one element for 38each repetition. 39 40Sometimes your input data structure isn't naturally in a suitable shape for 41use in a `for_each` argument, and `flatten` can be a useful helper function 42when reducing a nested data structure into a flat one. 43 44For example, consider a module that declares a variable like the following: 45 46```hcl 47variable "networks" { 48 type = map(object({ 49 cidr_block = string 50 subnets = map(object({ cidr_block = string })) 51 })) 52} 53``` 54 55The above is a reasonable way to model objects that naturally form a tree, 56such as top-level networks and their subnets. The repetition for the top-level 57networks can use this variable directly, because it's already in a form 58where the resulting instances match one-to-one with map elements: 59 60```hcl 61resource "aws_vpc" "example" { 62 for_each = var.networks 63 64 cidr_block = each.value.cidr_block 65} 66``` 67 68However, in order to declare all of the _subnets_ with a single `resource` 69block, we must first flatten the structure to produce a collection where each 70top-level element represents a single subnet: 71 72```hcl 73locals { 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 88resource "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 102The above results in one subnet instance per subnet object, while retaining 103the 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. 110