---
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`](/terraform/language/meta-arguments/for_each)
and
[`dynamic` block](/terraform/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`](/terraform/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.
