Let’s look at Terraform variable validation. I find it certainly useful when writing Terraform. This applies whether that be within a module or a direct resource update. Implementing the likes of variable validation helps you catch any potential errors early. This is certainly a great asset in preventing misconfigurations within your Terraform resources.
Understanding Terraform Variable Validation
Variable validation within Terraform has been around for a while, since 0.13. It allows you to define specific criteria that the variable input must match. Within this blog post, I will be showing some examples of this.
Firstly, lets look at the basic structure of variable validation, the block consists of two key components:
- The condition that the variable value must meet
- An error message that will appear if the conditional value is not met
variable "test" {
type = string
description = "Test variable"
validation {
condition =
error_message = "Error message if condition is not true."
}
}
Some Azure practical examples
My examples will be Azure focused, but variable validation can be used within any sort of Terraform configuration
Restricting Azure VM Sizes
You have a variable called azure_vm_size, that must use a VM size of Standard_D4ds_v5 or Standard_DS2_v4. Lets create the variable validation:
variable "azure_vm_size" {
type = string
description = "Size of the Azure VM"
validation {
condition = contains(["Standard_DS2_v4", "Standard_D4ds_v5"], var.vm_size)
error_message = "VM size can only be one of Standard_D4ds_v5, Standard_DS2_v4."
}
}
Notice above, variable validation now in place for azure_vm_size
Enforcing VM Naming Conventions
Lets look at variable validation to ensure the VM name must start with vm-tamops-*
variable "vm_name" {
type = string
description = "Name of the Azure resource group"
validation {
condition = can(regex("^vm-tamops", var.vm_name))
error_message = "VM Name name must start with 'vm-tamops'."
}
}
Similar as before, with the condition now using regex to capture the variable vm_name
Example Validating Resource Group Deployments
main.tf
resource "azurerm_resource_group" "tamopsrg" {
name = "${var.rg_name}-${var.environment}"
location = "West Europe"
}
variables.tf
variable "environment" {
description = "The environment for the resources"
type = string
validation {
condition = contains(["dev", "test", "prod"], var.environment)
error_message = "Environment must be one of 'dev', 'test', or 'prod'."
}
}
variable "rg_name" {
type = string
description = "Name of the Azure resource group"
validation {
condition = can(regex("^rg-tamops", var.rg_name))
error_message = "Resource group name must start with 'rg-tamops'."
}
}
examples.tfvars
environment = "preview"
rg_name = "tamops-rg"
Now when I run: terraform plan -var-file="example.tfvars" with incorrect variable values, see below. It gives clear error messaging as to why the current plan is failing. Awesome!
terraform plan -var-file="example.tfvars"
Planning failed. Terraform encountered an error while generating this plan.
╷
│ Error: Invalid value for variable
│
│ on example.tfvars line 1:
│ 1: environment = "preview"
│ ├────────────────
│ │ var.environment is "preview"
│
│ Environment must be one of 'dev', 'test', or 'prod'.
│
│ This was checked by the validation rule at variables.tf:4,3-13.
╵
╷
│ Error: Invalid value for variable
│
│ on example.tfvars line 2:
│ 2: rg_name = "tamops-rg"
│ ├────────────────
│ │ var.rg_name is "tamops-rg"
│
│ Resource group name must start with 'rg-tamops'.
│
│ This was checked by the validation rule at variables.tf:13,3-13.
Slightly more Complex Validation
With the beauty of variable validation, you can have it as simple or some-what complex as you want. Seeing below – an example
variable "ip_address" {
type = string
description = "Allowed IP that can be used"
validation {
condition = can(regex("^10\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", var.ip_address))
error_message = "The IP address must be within the range 10.0.0.0 to 10.255.255.255."
}
}
Example error output when IP address is not in the required range:
╷
│ Error: Invalid value for variable
│
│ on example.tfvars line 3:
│ 3: ip_address = "192.168.0.1"
│ ├────────────────
│ │ var.ip_address is "192.168.0.1"
│
│ The IP address must be within the range 10.0.0.0 to 10.255.255.255.
│
│ This was checked by the validation rule at variables.tf:22,3-13.
A few recommended best practices when using Terraform Variable Validation
- Use accurate and descriptive error messages: Just like any error messaging, provide clear and actionable error messages that will guide others to what the correct value(s) should be
- Make use of Terraform functions: Lots of functions available, with the likes of
can(),contains()andlength()are certainly useful for your variable validation - Possible to use multiple conditions: When your validations are getting more complex, you can use logical operators – such as
||and&& - Keep it Simple: Start simple and increase complexity only when needed
Terraform variable validation can be very useful. It is a powerful tool within your automation. Spend some time introducing it. You will certainly see the reward of improving reliability. It also enhances the maintainability of your Terraform configurations. By implementing thorough validations, you can catch configuration errors early. You can enforce best practices. This approach provides clear guidance to users of your Terraform configurations and modules.