You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a excerpt from one of my modules, used for creating additional block devices for an AWS EC2 instance like extra_volumes = {"/dev/sdf" = 100}, which I consider is a legitimate use case:
variable "extra_volumes" {
type = map(number)
validation {
# The `tomap` call is needed as otherwise it seems that Terraform v0.13.0
# interprets `{"key" = 1}` as of type `object({"key" = number})`.
# `length(var.extra_volumes) == 0` is needed as otherwise it seems that
# Terraform v0.13.0 interprets `{}` as the empty object and doesn't seem to
# be a way of cohersing that into `map(number)`.
# This is all by how Terraform defines equality: same value, same type:
condition = length(var.extra_volumes) == 0 || var.extra_volumes == tomap({
for k, v in var.extra_volumes :
k => v if can(regex("^/dev/sd[f-p]$", k)) && v >= 1
})
error_message = "Device must match /dev/sd[f-p]. Size must be positive."
}
}
My original approach, given the lack of all or any for collections, was
variable "extra_volumes" {
type = map(number)
validation {
condition = var.extra_volumes == {
for k, v in var.extra_volumes :
k => v if can(regex("^/dev/sd[f-p]$", k)) && v >= 1
})
error_message = "Device must match /dev/sd[f-p]. Size must be positive."
}
}
I think this more readable than current approach and feels more natural.
The text was updated successfully, but these errors were encountered:
The definition of the == operator is that the two arguments must have the same type and the same value, so unfortunately this behavior is as designed. We typically recommend using == primarily with primitive-typed values and using other techniques when writing conditionals about data structures.
In this case though, as you've seen an explicit tomap conversion can work because the for expression is deriving from a map(number) value and thus all of the attributes of the object have number type, and thus tomap will unify it into a map(number) result too and the result will match.
During 0.12 development we did experiment with making == do some special automatic type inference, but the result ended up still being confusing but even harder to explain than the current rule that the types must match, and so we settled on defining == as requiring type equality and using the type conversion functions to be explicit about what types are expected in situations where they don't naturally agree.
One thing that seems to have repeatedly come up with this sort of validation block that is making an assertion about an entire collection is that there isn't a function like sum which can take an arbitrary number of boolean values and return true only if they are all true, which makes it hard to write a simple can(...) call whose result derives from a collection. If we had a function all which took an arbitrary number of bool values then this could potentially be written a different way, with the can up at the top-level:
This then avoids the need to use == altogether and just reduces it to a statement about what condition must be true for each of the items in var.extra_volumes.
Hello team,
Terraform Version
Terraform Configuration Files
Debug Output
Crash Output
Does not apply.
Expected Behavior
Actual Behavior
Steps to Reproduce
The previous blocks are enough.
Additional Context
Does not apply.
References
Does not apply (after a quick search).
This is a excerpt from one of my modules, used for creating additional block devices for an AWS EC2 instance like
extra_volumes = {"/dev/sdf" = 100}
, which I consider is a legitimate use case:My original approach, given the lack of
all
orany
for collections, wasI think this more readable than current approach and feels more natural.
The text was updated successfully, but these errors were encountered: