Terraform v0.13 – Introducing Custom Variable Validation

Terraform v0.13 – Introducing Custom Variable Validation

Custom variable validation is now a production ready feature in the new Terraform v0.13 (Announced On June 22nd 2020 by HashiCorp)
Source – https://www.hashicorp.com/blog/announcing-the-terraform-0-13-beta/
This is great news because you can now ensure the data passed down matches the input variable validation you specify. If it doesn’t, Terraform will fail on the Terraform Plan step, listing the reason why the plan failed, which will be the error_message you specified in the input variable validation block, this is really handy because it stops resources from being created until they pass the required validation checks, which saves time, cost, and minimizes the risk of typos, and can even be used to enforce resource naming conventions.

So lets see how it works, in this example I am using Terraform v0.13-beta1.

I have kept it very simple, I am creating a ServiceBus Namespace Resource in Azure, but I would like some validation added, as a module author I do not want other developers using my ServiceBus module, to pass a really generic Resource Group Name, for example WEU, we would like at least 6 characters ideally and I want it to fail at the Terraform Plan step, not at the point when I check the available resources in Azure and panic at this naming convention.

ServiceBus Module.
Creates a ServiceBus Namespace in Azure, using three variables resource_group_name location and name.

resource "azurerm_resource_group" "service_bus" {
  name     = var.resource_group_name
  location = var.location
}

resource "azurerm_servicebus_namespace" "service_bus" {
  name                = "${var.name}-namespace"
  location            = azurerm_resource_group.service_bus.location
  resource_group_name = azurerm_resource_group.service_bus.name
  sku                 = "Standard"
}

resource "azurerm_servicebus_namespace_authorization_rule" "service_bus" {
  name                = "${var.name}-auth"
  namespace_name      = azurerm_servicebus_namespace.service_bus.name
  resource_group_name = azurerm_resource_group.service_bus.name
  send                = true
  listen              = true
  manage              = true
}

main.tf
This is the file that creates the ServiceBus Namespace by using the service bus module, and passing in the data for the required variables.

module "servicebus-namespace" {
  source              = "../../modules/servicebus"
  resource_group_name = "WEU"
  location            = "westeurope"
  name                = "test-sbn-weu-local-primary"
}

variables.tf
Here we declare the variables for the ServiceBus Module.

variable "resource_group_name" {
    type = string
    
    validation {
        condition = length(var.resource_group_name) > 6
        error_message = "The Resource Group Name Must Be More Than 6 Characters."
    }
}

variable "name" {
}

variable "location" {
}

As you can see from the code above, the resource_group_name variable has a validation section, this is where we can add validation rules to ensure the condition is satisfied before the plan is applied and resources are created in Azure.

As you can see, the code that creates the ServiceBus namespace, creates it with a Resource Group Name of WEU This is not an ideal naming convention and seems a bit too generic, that is why our condition above checks the length of the resource_group_name variable.

Running Terraform Plan you can see in the image below the validation fails as WEU is not more than 6 characters.

terraform variable validation

There is also regex support for Custom Validation Rules which would be great for enforcing naming convention rules.

You can read more about Custom Validation Rules on the Terraform Website here: https://www.terraform.io/docs/configuration/variables.html#custom-validation-rules

You can view the full code on my GitHub here. https://github.com/dpbeaumont/terraform/tree/master/examples/v13/variable-custom-validation-feature/infrastructure