Created
October 24, 2022 18:50
-
-
Save jonathanhle/eddc55bf1a6fad6c2e645c69c0011203 to your computer and use it in GitHub Desktop.
Terraform Variable Validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From https://andyhunt.me/til/2021/03/04/you-can-fully-validate-a-complex-input-object-in-terraform/ | |
You can fully validate a complex input object in Terraform | |
Posted: Thursday 04 March 2021 @ 12:12:55 | |
Terraform allows you to define your inputs as arbitrarily complex objects and lists of objects. For example, consider the following: | |
variable "instances" { | |
type = list(object({ | |
name = string | |
count = number | |
tags = map | |
})) | |
} | |
It describes an input which is a list of objects, which have name, count, and tags fields. You probably have some validation you'd like to apply to each of those objects, for example: | |
name must not be empty | |
count must be a multiple of 3 | |
tags must contain an business_unit tag | |
Terraform allows you to perform those validations using a validation block in the variable's definition. | |
The Terraform documentation shows a reasonably trivial example of validating a string, but it's also possible to validate lists, and lists of objects. Enter the alltrue function. | |
The alltrue function takes an array, and asserts that every entry is the value true. If you combine this with a Terraform for expression, you can produce an input to alltrue which is the result of applying a validation function to each element in the list. | |
You can start by writing a basic validation routine (for the above rules) for a single object. Assuming it's called instance, it might look like: | |
( length(instance.name) > 0 | |
&& (instance.count % 3) == 0 | |
&& lookup(instance.tags, "business_unit", null) != null | |
) | |
You can then combine this with a for expression to apply it to each object in a list, so that you're left with a list of boolean values: | |
[for instance in var.instances : ( | |
length(instance.name) > 0 | |
&& (instance.count % 3) == 0 | |
&& lookup(instance.tags, "business_unit", null) != null | |
)] | |
Finally, you can wrap this in the alltrue function to assert that every validation passed: | |
variable "instances" { | |
type = list(object({ | |
name = string | |
count = number | |
tags = map | |
})) | |
validation { | |
condition = ( | |
alltrue([for instance in var.instances : ( | |
length(instance.name) > 0 | |
&& (instance.count % 3) == 0 | |
&& lookup(instance.tags, "business_unit", null) != null | |
)]) | |
) | |
error_message = "Validation of an object failed" | |
} | |
} | |
Unfortunately, Terraform doesn't support multiple validation blocks for a single variable, so it isn't possible to provide a more useful error message. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment