Blog

Custom validation rules for Terraform input variables

01 Jan, 1970
Xebia Background Header Wave

In my previous post about Terraform input validation, I talked about using the file function to create input assertions. While this method is great if you need to do complex checks, where the outcome depends on multiple variables, Terraform does allow you to add validations to your variable definitions itself. In this post, I will give you some examples on how to use this functionality.

Limitations

When the validation option first came out in Terraform CLI v0.13.0, I got really excited. I hoped we could finally get rid of our custom assertions based on the file function as I talked about here. Unfortunately, I discovered the validations come with limitations. So before we get started, I will tell you about these limitations so you can decide if it will work for your use case beforehand.

Reference limitation

When writing your validation code, you can only compare the content passed to your variable to hard coded strings. This limits you in creation complex validations where you need to compare values passed to a different variable as well.

No variables allowed in error_message

You’re not allowed to use any variables in the error_message field. This makes it impossible to display a detailed error message. Terraform won’t tell you the input variable’s content, and not allowing the use of variables, it’s impossible to display this to the user yourself.

No dynamic support

Although there is an open ticket to add dynamic support to the validation rules, it’s currently not supported. This makes it harder to create validations for variables with an object type or map.

Simple validations

So now that we know the limitations, we can start writing our own validations. Looking at the Terraform documentation, we already see some examples. One example combines a length check with a string prefix check, and the other shows you how to use regular expressions to check the input value.
What isn’t entirely clear from the documentation, is the fact that you can define multiple validation blocks for each of your variables.
This allows you to do the following:

variable "prefix" {
  type        = string
  description = "The prefix used for the GCP projects"

  validation {
    condition     = can(regex("^w+$", var.project_prefix))
    # Not allowed due to the use of a variable:
    # error_message = "Invalid value [${var.prefix}]. The prefix value can only contain letters and numbers."
    error_message = "The prefix value can only contain letters and numbers."
  }

  validation {
    condition     = length(var.project_prefix) > 2 && ength(var.project_prefix) <= 6
    # Not allowed due to the use of a variable:
    # error_message = "Invalid value [${var.prefix}]. The prefix value should contain at least 3 characters and can not contain more than 6 characters"
    error_message = "The prefix value should contain at least 3 characters and can not contain more than 6 characters"
  }
}

Validating complex types

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts