patternterraformMinor
Terraform variable Validation
Viewed 0 times
variablevalidationterraform
Problem
is it possible to use validation of a variable type equals list(string)?
My example:
main.tf
vars.tf
When I try execute returns the following error:
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 1Solution
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
If you are using Terraform v0.13 then you won't have the
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:
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 ofvar.security_groupsto 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 theforexpression will be empty unless there's at least one invalid value.
- Finally, the
length( ... ) == 0around theforexpression 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.
Code Snippets
validation {
condition = alltrue([
for id in var.security_groups : can(regex("^sg-", id))
])
error_message = "All security group ids must start with \"sg-\"."
}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-\"."
}Context
StackExchange DevOps Q#13092, answer score: 4
Revisions (0)
No revisions yet.