Logo

dev-resources.site

for different kinds of informations.

Terraform: Variable validation with samples

Published at
3/4/2022
Categories
terraform
linting
Author
drewmullen
Categories
2 categories in total
terraform
open
linting
open
Author
10 person written this
drewmullen
open
Terraform: Variable validation with samples

Terraform allows you to validate variable input in using validation blocks using custom condition and yielding a custom error_message. Below are some examples:

Note: Please share your common validation rules you've written and I'll update here

Update: Please check out this awesome project by @bschaatsbergen that provides built in functions for assertions: https://github.com/bschaatsbergen/terraform-provider-assert

Strings

String may not contain character

Scenario: String may not contain a /.

variable "string_may_not_contain" {
  type = string
  default = "test"

  validation {
    error_message = "Value cannot contain a \"/\"."
    condition = !can(regex("/", var.string_may_not_contain))
  }
}
Enter fullscreen mode Exit fullscreen mode

String with valid options

Scenario: Here we have a string and we only allow to values "approved" or "disapproved". I show 2 examples of the same check using different methods:

variable "string_only_valid_options" {
  type = string
  default = "approved"

  # using regex
  validation {
    condition     = can(regex("^(approved|disapproved)$", var.string_only_valid_options))
    error_message = "Invalid input, options: \"approved\", \"disapproved\"."
  }

  # using contains()
  validation {
    condition     = contains(["approved", "disapproved"], var.string_only_valid_options)
    error_message = "Invalid input, options: \"approved\", \"disapproved\"."
  }
}
Enter fullscreen mode Exit fullscreen mode

Valid AWS Region Name

Scenario: string must be like AWS region

variable "string_like_aws_region" {
  type = string
  default = "us-east-1"

  validation {
    condition     = can(regex("[a-z][a-z]-[a-z]+-[1-9]", var.string_like_aws_region))
    error_message = "Must be valid AWS Region names."
  }
Enter fullscreen mode Exit fullscreen mode

Valid IAM Role Name

Scenario: Your string must be a valid IAM role name

variable "string_valid_iam_role_name" {
    type = string
    default = "MyCoolRole"
    # arn example: "arn:aws:iam::123456789012:role/MyCoolRole"

    validation {
      condition     = can(regex("^[a-zA-Z][a-zA-Z\\-\\_0-9]{1,64}$", var.string_valid_iam_role_name))
      error_message = "IAM role name must start with letter, only contain letters, numbers, dashes, or underscores and must be between 1 and 64 characters."
    }
}
Enter fullscreen mode Exit fullscreen mode

Valid IPv4 CIDR

Scenario: Your string input needs to look like a IPv4 CIDR. Thank you @entscheidungsproblem for reporting and providing a fix for /32.

variable "string_like_valid_ipv4_cidr" {
  type    = string
  default = "10.0.0.0/16"

  validation {
    condition     = can(cidrhost(var.string_like_valid_ipv4_cidr, 0))
    error_message = "Must be valid IPv4 CIDR."
  }
}
Enter fullscreen mode Exit fullscreen mode

Semantic Version

variable "semv1" {
  default = "10.57.123"

  validation {
    error_message = "Must be valid semantic version."
    condition     = can(regex("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", var.semv1))
  }
}
Enter fullscreen mode Exit fullscreen mode

Maps

Map with optional conflicting keys

Scenario: You have a map variable and 2 keys conflict, in this case, you can only set either cidr or netmask.

variable "only_one_optional_key" {
    type = object({
        name = optional(string)
        cidrs = optional(list(string))
        netmask = optional(number)
    })

    default = {
        cidr = "10.0.0.0/16"
        name = "test"
    }

    validation {
        error_message = "Can only specify either \"cidrs\", or \"netmask\"."
        condition = length(setintersection(keys(var.only_one_optional_key), ["cidrs", "netmask"])) == 1
    }
}
Enter fullscreen mode Exit fullscreen mode

Numbers

Number within a range

Scenario: number must be between 1-16.
Thanks: @tlindsay42

variable "num_in_range" {
  type        = number
  default     = 1

  validation {
    condition     = var.num_in_range >= 1 && var.num_in_range <= 16 && floor(var.num_in_range) == var.num_in_range
    error_message = "Accepted values: 1-16."
  }
}
Enter fullscreen mode Exit fullscreen mode

If you liked this post, please like. If you think it would be helpful in the future as a reference, please bookmark!

linting Article's
30 articles in total
Favicon
How to Configure VSCode for Auto Formatting and Linting in Python
Favicon
Level Up Your OpenAPI Specs using Linting
Favicon
Most elemental code formatting for Typescript/Javascript: .editorconfig vs prettier
Favicon
standardrb, but more
Favicon
Introducing Japr - The Project Linter
Favicon
Level Up Your TypeScript Projects: Discover the Power of ESLint and Prettier
Favicon
Interview with Greg Molnar - Rails developer and penetration tester
Favicon
Setting WordPress Coding Standards per project using Composer
Favicon
Linting Proto Files With Buf
Favicon
ESLint: The Hows, Whys, and Who Behind It
Favicon
Puppet-lint: Soft dependency conflicts after updating
Favicon
Eslint rule to restrict imports
Favicon
Laravel Tooling: 4 tools for static analysis
Favicon
Terraform: Variable validation with samples
Favicon
An Incremental Approach to Linting to Your Projects
Favicon
Add EsLint to existing Angular Project and Configure WebStorm
Favicon
Quick ESLint guide + VsCode ESLint on save
Favicon
Chickity-check yo self before you wreck yo self!
Favicon
How to configure Eslint in Gatsby projects
Favicon
Automatically sorting your Tailwind CSS class names
Favicon
Setting up ESLint + Prettier
Favicon
Incrementally adding Stylelint rules with Betterer
Favicon
Conventional Git Commit Messages and Linting
Favicon
ยฟQuรฉ es Linting y ESLint?
Favicon
My 2020 Python linting setup: How I Learned to Stop Worrying and Love the automated code formatting
Favicon
ESLint not working in VSCode? Help build a troubleshooting checklist!
Favicon
SERIES: React Native (Step by Step) - Working with Typescript and Linting
Favicon
Adding Markdown Linting to my Blogโ€™s Build Process with GitHub Actions and markdownlint
Favicon
TIL - ๐Ÿงน unimport linter formatter
Favicon
Adding New Lint Rules Without the Fuss

Featured ones: