<p>When validating an input variable of a collection type, we typically want to write a validation rule that tests if something is true for each value within the collection, rather than true of the collection as a whole.</p>
<p>You can write a &quot;for each&quot; sort of condition using Terraform's <a href="https://www.terraform.io/docs/configuration/expressions/for.html" rel="nofollow noreferrer"><code>for</code> expressions</a>. If you are using Terraform v0.14 or later then you can write it concisely using <a href="https://www.terraform.io/docs/configuration/functions/alltrue.html" rel="nofollow noreferrer">the <code>alltrue</code> function</a> along with a <code>for</code> expression that produces a true or false result for each of the items, like this:</p>
<pre><code>  validation {
    condition = alltrue([
      for id in var.security_groups : can(regex(&quot;^sg-&quot;, id))
    ])
    error_message = &quot;All security group ids must start with \&quot;sg-\&quot;.&quot;
  }
</code></pre>
<hr />
<p>If you are using Terraform v0.13 then you won't have the <code>alltrue</code> function available to you yet, but you can get a similar result in a clunkier way by using the optional <code>if</code> clause of a <code>for</code> expression to filter out all of the valid ids and then checking whether the resulting list is empty -- that is, whether there are any remaining items that were <em>not</em> valid:</p>
<pre><code>  validation {
    condition = length([
      for id in var.security_groups : id
      if !can(regex(&quot;^sg-&quot;, id))
    ]) == 0
    error_message = &quot;All security group ids must start with \&quot;sg-\&quot;.&quot;
  }
</code></pre>
<p>This second example is a bit more cryptic to understand because it's using some language features in an atypical way, so I'll break it down into smaller parts to explain:</p>
<ul>
<li><code>[for id in var.security_groups : id if !can(regex(&quot;^sg-&quot;, id))]</code> filters the elements of <code>var.security_groups</code> to keep only the ones where the expression is true.</li>
<li><code>!can(regex(&quot;^sg-&quot;, id))</code> uses the <code>!</code> operator to turn your original expression that decides if the value is <em>valid</em> into an expression which decides if the value is <em>invalid</em>. Consequently the result of the <code>for</code> expression will be empty unless there's at least one invalid value.</li>
<li>Finally, the <code>length( ... ) == 0</code> around the <code>for</code> expression says that the value is only valid if filtering out all of the valid values produces an empty list, which conversely means that the list didn't contain any invalid values.</li>
</ul>

CC BY-SA 4.0
2021-01-06T13:57:33.237Z
thanks for help.
Vader
CC BY-SA 4.0
2021-01-06T00:55:15.363Z
2021-01-06T17:27:23.473Z
2021-01-06T17:27:23.473Z
Martin Atkins
<p>is it possible to use validation of a variable type equals list(string)?</p>
<p>My example:</p>
<p><strong>main.tf</strong></p>
<pre><code>  name            = &quot;tf-prd-sg-foo&quot;
  image_id        = &quot;ami-00e788542ee66c64f&quot;
  instance_type   = &quot;m5.xlarge&quot;
  security_groups = [&quot;sg-000000&quot;, &quot;sg-00000000&quot;] # Example of SG only to contextualize
}
</code></pre>
<p><strong>vars.tf</strong></p>
<pre><code>variable &quot;security_groups&quot;  {
    type        = list(string)
    default     = [] 
    description = &quot;(Optional) A list of associated security group IDS.&quot;

    validation {
      condition = can(regex(&quot;^sg-&quot;, var.security_groups))
      error_message = &quot;The Security Groups need starts to \&quot;sg-\&quot;.&quot;
    }
}
</code></pre>
<p>When I try execute returns the following error:</p>
<pre><code>[terragrunt] 2021/01/05 17:12:10 Running command: terraform plan

Error: Invalid value for variable

  on vars.tf line 21:
  21: variable &quot;security_groups&quot;  {

The Security Groups need starts to &quot;sg-&quot;.

This was checked by the validation rule at vars.tf:26,5-15.

[terragrunt] 2021/01/05 17:12:12 Hit multiple errors:
exit status 1


</code></pre>

<terraform><terragrunt><aws-security-group>
Terraform variable Validation
Vader
# Terraform variable Validation

(Asked by: username_0 on 2021-01-05)

is it possible to use validation of a variable type equals list(string)?
My example:
main.tf
  name            = "tf-prd-sg-foo"
  image_id        = "ami-00e788542ee66c64f"
  instance_type   = "m5.xlarge"
  security_groups = ["sg-000000", "sg-00000000"] # Example of SG only to contextualize
}

vars.tf
variable "security_groups"  {
    type        = list(string)
    default     = [] 
    description = "(Optional) A list of associated security group IDS."

    validation {
      condition = can(regex("^sg-", var.security_groups))
      error_message = "The Security Groups need starts to \"sg-\"."
    }
}

When I try execute returns the following error:
[terragrunt] 2021/01/05 17:12:10 Running command: terraform plan

Error: Invalid value for variable

  on vars.tf line 21:
  21: variable "security_groups"  {

The Security Groups need starts to "sg-".

This was checked by the validation rule at vars.tf:26,5-15.

[terragrunt] 2021/01/05 17:12:12 Hit multiple errors:
exit status 1

**Tags:** terraform, terragrunt, aws-security-group


---

## 1 answers

### Answer by username_1 on 2021-01-06. Score: 4 | Accepted answer

When validating an input variable of a collection type, we typically want to write a validation rule that tests if something is true for each value within the collection, rather than true of the collection as a whole.
You can write a "for each" sort of condition using Terraform's for expressions. If you are using Terraform v0.14 or later then you can write it concisely using the alltrue function along with a for expression that produces a true or false result for each of the items, like this:
  validation {
    condition = alltrue([
      for id in var.security_groups : can(regex("^sg-", id))
    ])
    error_message = "All security group ids must start with \"sg-\"."
  }


If you are using Terraform v0.13 then you won't have the alltrue function available to you yet, but you can get a similar result in a clunkier way by using the optional if clause of a for expression to filter out all of the valid ids and then checking whether the resulting list is empty -- that is, whether there are any remaining items that were not valid:
  validation {
    condition = length([
      for id in var.security_groups : id
      if !can(regex("^sg-", id))
    ]) == 0
    error_message = "All security group ids must start with \"sg-\"."
  }

This second example is a bit more cryptic to understand because it's using some language features in an atypical way, so I'll break it down into smaller parts to explain:

[for id in var.security_groups : id if !can(regex("^sg-", id))] filters the elements of var.security_groups to keep only the ones where the expression is true.
!can(regex("^sg-", id)) uses the ! operator to turn your original expression that decides if the value is valid into an expression which decides if the value is invalid. Consequently the result of the for expression will be empty unless there's at least one invalid value.
Finally, the length( ... ) == 0 around the for expression says that the value is only valid if filtering out all of the valid values produces an empty list, which conversely means that the list didn't contain any invalid values.

> **Comments:**
> **username_0**: thanks for help.  

---

