<p>Following the documentation a <code>map</code> is a collection of key/values with a constraint:</p>
<blockquote>
<p>&quot;...accepts any element type as long as every element is the same type&quot; <a href="https://www.terraform.io/docs/configuration/types.html#map-" rel="nofollow noreferrer">source</a></p>
</blockquote>
<p>So the input map you have declared, is already an invalid map for Terraform 0.12 (at least)</p>
<p>Below the example of the error produced:</p>
<pre><code>variable &quot;cidrs&quot; {
  description = &quot;&quot;
  type        = map
  default = [
    [&quot;1.1.1.1&quot;],
    [&quot;2.2.2.2&quot;, &quot;3.3.3.3&quot;],
    {
      C = [&quot;4.4.4.4&quot;]
      D = [&quot;5.5.5.5&quot;]
    }]
}
</code></pre>
<p>When validating an error is raised:</p>
<pre><code>$&gt; terraform validate

Error: Invalid default value for variable

  on vars.tf line 65, in variable &quot;cidrs&quot;:
  65:   default = [
  66:     [&quot;1.1.1.1&quot;],
  67:     [&quot;2.2.2.2&quot;, &quot;3.3.3.3&quot;],
  68:     {
  69:       C = [&quot;4.4.4.4&quot;]
  70:       D = [&quot;5.5.5.5&quot;]
  71:     }]

This default value is not compatible with the variable's type constraint: map
of any single type required.
</code></pre>
<p>Been that said, if we can generalize A and B as &quot;values which are lists&quot; and Group1 as &quot;values which are maps&quot; and the input is a fixed type ordered we can use a <em><a href="https://www.terraform.io/docs/configuration/types.html#tuple-" rel="nofollow noreferrer">tuple</a></em> or  an <em><a href="https://www.terraform.io/docs/configuration/types.html#object-" rel="nofollow noreferrer">object</a></em>, this can be solve in a more readable (and maintainable) way. If so, let us know so we can extend this answer.</p>

CC BY-SA 4.0
2020-08-03T22:44:21.240Z
2020-08-06T16:08:01.087Z
2020-08-06T16:08:01.087Z
Rafael Aguilar
<p>I want to take a map such as this that is passed in as a variable</p>
<pre><code>cidrs = {
  A = [1.1.1.1]
  B = [2.2.2.2, 3.3.3.3]
  Group1 = {
    C = [4.4.4.4]
    D = [5.5.5.5]
  }
}
</code></pre>
<p>and then within the locals section i want to sanitize it to the following</p>
<pre><code>cidrs_sanitized = {
  A = [1.1.1.1]
  B = [2.2.2.2, 3.3.3.3]
  Group1 = [4.4.4.4, 5.5.5.5]
  C = [4.4.4.4]
  D = [5.5.5.5]
}
</code></pre>
<p>I have tried various methods of looping</p>
<p>everything i've tried so far has led to me trying to get each set of values as seperate variables and then merge them together example:</p>
<pre><code>single = { A = [1.1.1.1], B = [2.2.2.2, 3.3.3.3] }
groups = { Group1 = [4.4.4.4, 5.5.5.5] }
grouped = { C = [4.4.4.4], D = [5.5.5.5] }
cidrs_sanitized = merge(single, groups, grouped)
</code></pre>
<p>and here's some of the stuff i've tried but failed to succeed with</p>
<pre><code>groups = flatten([ for range, value in var.cidrs: tomap({ range = values(value) }) if !can(element(value, 0)) ])
single = flatten([ for range, value in var.cidrs: tomap({ range = value }) if can(element(value, 0)) ])
</code></pre>
<p>and</p>
<pre><code>groups = {
  for range, value in var.ranges :
    range =&gt; can(values(value)) ? values(value) : null
}
grouped = flatten([for range in var.ranges : [
  for cidr_key, cidr in range : {
    cidr_key =&gt; cidr
  } if length(cidr) &gt; 0
] if can(values(range)) ])
</code></pre>
<p>The merge always fails as it tells me the output are tuples and i can't figure out how to get terraform to show me the values of the locals grouped, groups and single when calling it as a module</p>
<p>Any help or points in the right direction would be appreciated, thanks.</p>

<terraform>
Terraform: Sanitize a map that may be a map of strings or map of maps or combo of both
Cyber Axe
# Terraform: Sanitize a map that may be a map of strings or map of maps or combo of both

(Asked by: username_0 on 2020-07-29)

I want to take a map such as this that is passed in as a variable
cidrs = {
  A = [1.1.1.1]
  B = [2.2.2.2, 3.3.3.3]
  Group1 = {
    C = [4.4.4.4]
    D = [5.5.5.5]
  }
}

and then within the locals section i want to sanitize it to the following
cidrs_sanitized = {
  A = [1.1.1.1]
  B = [2.2.2.2, 3.3.3.3]
  Group1 = [4.4.4.4, 5.5.5.5]
  C = [4.4.4.4]
  D = [5.5.5.5]
}

I have tried various methods of looping
everything i've tried so far has led to me trying to get each set of values as seperate variables and then merge them together example:
single = { A = [1.1.1.1], B = [2.2.2.2, 3.3.3.3] }
groups = { Group1 = [4.4.4.4, 5.5.5.5] }
grouped = { C = [4.4.4.4], D = [5.5.5.5] }
cidrs_sanitized = merge(single, groups, grouped)

and here's some of the stuff i've tried but failed to succeed with
groups = flatten([ for range, value in var.cidrs: tomap({ range = values(value) }) if !can(element(value, 0)) ])
single = flatten([ for range, value in var.cidrs: tomap({ range = value }) if can(element(value, 0)) ])

and
groups = {
  for range, value in var.ranges :
    range => can(values(value)) ? values(value) : null
}
grouped = flatten([for range in var.ranges : [
  for cidr_key, cidr in range : {
    cidr_key => cidr
  } if length(cidr) > 0
] if can(values(range)) ])

The merge always fails as it tells me the output are tuples and i can't figure out how to get terraform to show me the values of the locals grouped, groups and single when calling it as a module
Any help or points in the right direction would be appreciated, thanks.

**Tags:** terraform


---

## 1 answers

### Answer by username_1 on 2020-08-03. Score: 1

Following the documentation a map is a collection of key/values with a constraint:

"...accepts any element type as long as every element is the same type" source

So the input map you have declared, is already an invalid map for Terraform 0.12 (at least)
Below the example of the error produced:
variable "cidrs" {
  description = ""
  type        = map
  default = [
    ["1.1.1.1"],
    ["2.2.2.2", "3.3.3.3"],
    {
      C = ["4.4.4.4"]
      D = ["5.5.5.5"]
    }]
}

When validating an error is raised:
$> terraform validate

Error: Invalid default value for variable

  on vars.tf line 65, in variable "cidrs":
  65:   default = [
  66:     ["1.1.1.1"],
  67:     ["2.2.2.2", "3.3.3.3"],
  68:     {
  69:       C = ["4.4.4.4"]
  70:       D = ["5.5.5.5"]
  71:     }]

This default value is not compatible with the variable's type constraint: map
of any single type required.

Been that said, if we can generalize A and B as "values which are lists" and Group1 as "values which are maps" and the input is a fixed type ordered we can use a tuple or  an object, this can be solve in a more readable (and maintainable) way. If so, let us know so we can extend this answer.


---

