In Terraform, we use Variables to make projects configurable and to reduce code duplication. We can harden variables, by applying individual validations to them.
Obviously, providers like the official Azure Provider come with validations on resource attributes. For example, consider describing an instance of Azure Container Registry (ACR).
ACR has several required
attributes, which must be provided by consumers. If consumers forget specifying a required
attribute, Terraform will not try to provision it. Instead, the operation will fail and report a corresponding error message to the user, as shown in figure 1.
Another great example for custom validation is the sku
property. You have to set the value of sku
either to Basic
, Standard
, Premium
. The provider will accept no other values. If consumers provide a different value, Terraform will again produce a meaningful error message and stop the execution.
Having critical properties being protected with built-in validation logic is fantastic. However, sometimes you may want to use different validation logic in the scope of your project, which is an excellent scenario for custom validations.
Custom Validation Rules in Terraform
Consider the previously explained sku
property on a resource of type azurerm_container_registry
. Technically, it accepts one of the three values mentioned before. In the scope of our fictive project, only services with an SKU of Standard
or Premium
are allowed. To achieve this, we will use a custom validation.
Custom validations are currently flagged as experimental feature, which means you have to turn them on explicitly in the context of your project. To do so, update your terraform
block and add support for the experimental feature:
terraform {
experiments = [variable_validation]
}
To specify the sku
, we start with a simple Terraform variable.
variable "acr_sku" {
type = string
description = "Azure Container Registry SKU"
}
The variable is used in the azurerm_container_registry
resource, to set sku
:
resource "azurerm_resource_group" "main" {
name = "rg-main"
location = "westeruope"
}
resource "azurerm_container_registry" "acr" {
name = "thnsblogdemo"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
sku = var.acr_sku
}
Having such a configuration, consumers can specify the desired SKU by providing a value for acr_sku
. For example, an explicit specification as part of terraform apply
could look like this:
terraform apply -var acr_sku="Standard"
To prevent users from specifying Basic
, we can now add custom validation logic to the variable:
variable "acr_sku" {
type = string
description = "Azure Container Registry SKU"
validation {
condition = var.acr_sku == "Standard" || var.acr_sku == "Premium"
error_message = "Sorry, but we only accept ACRs on Standard or Premium SKU."
}
}
Terraform CLI will present your custom error_message
if the condition evaluates to false
.
At the moment, you can access the hosting variable within your validation logic; you are not able to take another variable into consideration to provide even complex validation.
If consumers specify Basic
as value for acr_sku
now, Terraform will display the custom error message, as shown in figure 3.
Have you already used custom validations in Terraform projects? What is your opinion about the current state? Leave a comment and let us talk about it. Also, make sure that you have subscribed to my newsletter to get an instant ping when new articles are published here.