Hi there,
I’m using a Terraform module to create some resources.
The resources themselves have mandatory and optional attributes and some of the attributes are validated (and this is the problem).
My problem statement is:
I want to validate the content of optional keys in a map.
Keys are either present and the content must get validated,
OR the keys are not present, which is also okay.
Here’s some example of the resource-values I use while developing with Terraform console:
locals {
my_teams = {
"team1" = {
name = "Some Tea Team"
short_name = "STT"
contact_email = "team-stt@example.com"
}
"team2" = {
name = "Something with Network"
short_name = "NET"
contact_email = "network@example.com"
billing_contact_email = "network-billing@example.com"
}
"team3" = {
name = "Some Utilities Creators"
short_name = "SUSI"
contact_email = "team-susi@example.com"
billing_contact_email = "team-susi-billing@example.com"
}
}
}
The contact_email
is mandatory, the billing_contact_email
is optional.
I want to do regex-validation on both attributes.
I used terraform console
with only this snippet (above) to come up with this condition for my validation:
alltrue([for key, team in local.my_teams : (lookup(team, "billing_contact_email", "<NONE>") == "<NONE>" ? true : (can(regex("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", lookup(team, "billing_contact_email", "ERROR!")))))]
In pseudo-code:
lookup the key “billing_contact_email”
if there’s no key → output = “<NONE>” → return “true” to the validate-function
if there is the key → apply regex to the value of the key → return “true” or “false” as a result
The alltrue()
function can get removed for better debugging. → this snippet works nicely (and yes, I restarted terraform console
after chaning my code-snippet )
Code in the terraform module:
variable "my_teams" {
type = map(object({
name = string
short_name = string
contact_email = string
billing_contact_email = optional(string)
tags = optional(map(string), {})
}))
description = "My Teams"
validation {
condition = alltrue([for key, team in var.my_teams : can(regex("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", lookup(team, "contact_email", "<NONE>")))])
error_message = "Attribute 'contact_email' not set or it's value is not a valid email address."
}
validation {
condition = alltrue(
[for key, team in var.my_teams : (lookup(team, "billing_contact_email", "<NONE>") == "<NONE>" ? true : (can(regex("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", lookup(team, "billing_contact_email", "ERROR!")))))]
)
error_message = "Attribute 'billing_contact_email' has not a valid email address as a value."
}
}
How the module is called:
module "team_hierarchy" {
source = "../modules/team-creation"
org_unit = "My Organization"
my_teams = {
"team1" = {
name = "Some Tea Team"
short_name = "STT"
contact_email = "team-stt@example.com"
}
"team2" = {
name = "Something with Network"
short_name = "NET"
contact_email = "network@example.com"
billing_contact_email = "network-billing@example.com"
}
"team3" = {
name = "Some Utilities Creators"
short_name = "SUSI"
contact_email = "team-susi@example.com"
billing_contact_email = "team-susi-billing@example.com"
}
}
}
The code is identically, only the variable is named differently.
How come the results are so different?
There is no dynamic data involved, every change is applied, and I only want to add the validation.
How can I solve my validation-problem and why do I get different results?
Similar issue: Different result during terraform plan & console