---
page_title: flatten - Functions - Configuration Language
description: The flatten function eliminates nested lists from a list.
---

# `flatten` Function

`flatten` takes a list and replaces any elements that are lists with a
flattened sequence of the list contents.

## Examples

```
> flatten([["a", "b"], [], ["c"]])
["a", "b", "c"]
```

If any of the nested lists also contain directly-nested lists, these too are
flattened recursively:

```
> flatten([[["a", "b"], []], ["c"]])
["a", "b", "c"]
```

Indirectly-nested lists, such as those in maps, are _not_ flattened.

## Flattening nested structures for `for_each`

The
[resource `for_each`](/language/meta-arguments/for_each)
and
[`dynamic` block](/language/expressions/dynamic-blocks)
language features both require a collection value that has one element for
each repetition.

Sometimes your input data structure isn't naturally in a suitable shape for
use in a `for_each` argument, and `flatten` can be a useful helper function
when reducing a nested data structure into a flat one.

For example, consider a module that declares a variable like the following:

```hcl
variable "networks" {
  type = map(object({
    cidr_block = string
    subnets    = map(object({ cidr_block = string }))
  }))
}
```

The above is a reasonable way to model objects that naturally form a tree,
such as top-level networks and their subnets. The repetition for the top-level
networks can use this variable directly, because it's already in a form
where the resulting instances match one-to-one with map elements:

```hcl
resource "aws_vpc" "example" {
  for_each = var.networks

  cidr_block = each.value.cidr_block
}
```

However, in order to declare all of the _subnets_ with a single `resource`
block, we must first flatten the structure to produce a collection where each
top-level element represents a single subnet:

```hcl
locals {
  # flatten ensures that this local value is a flat list of objects, rather
  # than a list of lists of objects.
  network_subnets = flatten([
    for network_key, network in var.networks : [
      for subnet_key, subnet in network.subnets : {
        network_key = network_key
        subnet_key  = subnet_key
        network_id  = aws_vpc.example[network_key].id
        cidr_block  = subnet.cidr_block
      }
    ]
  ])
}

resource "aws_subnet" "example" {
  # local.network_subnets is a list, so we must now project it into a map
  # where each key is unique. We'll combine the network and subnet keys to
  # produce a single unique key per instance.
  for_each = {
    for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
  }

  vpc_id            = each.value.network_id
  availability_zone = each.value.subnet_key
  cidr_block        = each.value.cidr_block
}
```

The above results in one subnet instance per subnet object, while retaining
the associations between the subnets and their containing networks.

## Related Functions

* [`setproduct`](/language/functions/setproduct) finds all of the combinations of multiple
  lists or sets of values, which can also be useful when preparing collections
  for use with `for_each` constructs.
