Hi @cvalentin-dkt,
It looks like you’re very close here. The trick is that the expression in the “true” arm of the conditional expression must also return a true or false depending on whether it’s valid, rather than an error, and so I think it would be sufficient to put just that regex
call in a can
to get that effect:
variable "example_json" {
type = string
validation {
condition = (
can(jsondecode(var.dashboard)) ?
can(regex("^[Monitoring]", jsondecode(var.dashboard).title)) :
false
)
error_message = "Must be valid JSON and have Title set to \"example\"."
}
}
Another way to write it which avoids duplicating the jsonencode
call is to use try
, which is similar to can
except it returns the first argument whose evaluation succeeds rather than returning a boolean to indicate whether a single argument succeeded. We can therefore use try
to provide a fallback value to use if the dashboard string isn’t valid JSON:
condition = can(regex(
"^[Monitoring]",
try(jsondecode(var.dashboard).title, "")
))
The inner try
here says to try to JSON decode the dashboard string and access .title
from the result, but if any of that fails just use an empty string instead, which will then fail the regular expression because it doesn’t have one of the expected prefixes, and so it’ll still produce the validation error in that situation.
I think one remaining problem is of regular expression syntax rather than Terraform syntax. The regular expression [Monitoring]
means to match a single character that must be one of the characters in the brackets (any of the letters “Monitrg” in this case). I think you intended to use ()
parentheses to describe the precedence for the |
operator:
condition = can(regex(
"^(Monitoring|OtherExample)",
try(jsondecode(var.dashboard).title, "")
))
Putting this altogether it requires that the following all be true:
- The given string is valid JSON (or
jsonencode
would fail) - The data structure described by the JSON is an object with a property named
title
(or.title
would fail) - The value of
title
is a string or convertible to a string (orregex
would reject it as being of an unsupported type) - That the string representation of
title
starts with eitherMonitoring
orOtherExample
(orregex
would reject it as not matching the pattern)