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.
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