Dynamic validation in locals or validation

Right now i dont see an option to validate variables in locals block…is there a provision to add dynamic in locals too
for example i have a list of comma seperated container names used while storage account creation… i wanted to validate each container name… how do i do it now…
var.othercontainer_name for example is “abc,cfr,ggg,ddd” is a comma separated list of strings

locals {
containers = “${var.othercontainer_name!=” " ? split(",", trimspace(var.othercontainer_name)) : }"

dynamic “validation”{
for_each = local.containers
content{
condition = (
length(containers.value) >= 3 &&
length(containers.value) <= 24 &&
can(regex("[1]+$", containers.value))
)
error_message = “Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only.”
}
}
}


  1. 0-9a-z ↩︎

Hi @venrass!

Your example seems to combine the syntax from at least three separate features in a way where I’m not sure how to understand what effect you intended.

Can you also explain your goal in natural language so that I can hopefully understand better what your intent was? Thanks!

basically i have a variable var.othercontainer_name.

Value in this variable is comma separated string example

“abc,xyz,jkl”

now i am going to split this string to array
so i have string array now [“abc”,“xyz”,“kjl”]

for each string in this array i want to run a validation… to see if the length of each string is <3 and >24 charachers… if any string didnt pass the validation, i need to fail the validation with error message

Thanks for the extra context, @venrass!

Terraform expects validation rules and other custom conditions to be associated with the object that relies on them, rather than with the value itself, and so I think the best answer for your problem with today’s Terraform is to write this as a validation rule in your variable "othercontainer_name" block.

You can use the alltrue function as part of a condition that checks whether some role holds for every element of a collection. In your case, I think the structure would be something like this:

  validation {
    condition = alltrue([
      for s in split(",", trimspace(var.othercontainer_name)) :
      can(regex("[a-z0-9]+$", containers.value))
    ])
    # ...
  }

You can also write a separate validation block to check that the length of the list is within the required range. Terraform will not consider the value valid unless all validation rules pass, so multiple validation blocks is equivalent to a single one with && combining several conditions, except that separate blocks means you can specify a different error message for each situation.

Tangentially, it feels a bit strange to me for a module to take a string with comma-separated tokens in it rather than just declaring the variable as a list or set of strings directly and having the caller be the one to split a string if that is applicable to a particular situation. I would typically recommend using the most relevant type for any given situation and then converting data in the caller if necessary, so that the interface to your module is easy to understand from the type constraints. That doesn’t significantly change my answer above, except that you would no longer need to keep writing the split function call in each separate location where you make use of the variable; it would only be done once in the calling module instead.

Thank you that works