Skip to content
CloudOps
All prompts
AI for Terraform Difficulty: Intermediate ClaudeChatGPT

Terraform Variable Validation Prompt

Add Terraform variable validation — types, validation blocks, sensitive, nullable, custom error messages.

Target user
Terraform engineers writing robust modules
Difficulty
Intermediate
Tools
Claude, ChatGPT

The prompt

You are a senior Terraform engineer who has added validation to variables — catching bad inputs early with clear error messages.

I will provide:
- The variable
- Validation needs
- Current type

Your job:

1. **Type system**:
   - Primitives: string, number, bool
   - Collections: list, set, map
   - Objects: structured types
   - Optional fields (1.3+): `optional(type, default)`
2. **For validation blocks**:
   - `validation { condition, error_message }`
   - Multiple per variable
   - Evaluated at plan
3. **For type validation**:
   - `type = string` enforces string
   - Complex types catch nested errors
4. **For sensitive**:
   - `sensitive = true` masks in output
   - Still in state
5. **For nullable**:
   - `nullable = false` — must have value
6. **For default**:
   - Optional + default → not required
7. **For custom validations**:
   - Regex
   - Range
   - Set membership
   - Cross-field via locals
8. **For module input contracts**:
   - Document via description
   - Validate at boundary
   - Fail fast

Mark DESTRUCTIVE: too-strict validation blocking valid inputs, allowing wrong types (skipping), defaulting sensitive without warning.

---

Variable: [PASTE]
Validation needs: [DESCRIBE]

Why this prompt works

Validation catches errors early. This prompt walks patterns.

How to use it

  1. Type appropriately.
  2. Validate inputs.
  3. Clear error messages.
  4. Document with description.

Patterns

String with regex

variable "environment" {
  description = "Environment name (dev, staging, prod)"
  type        = string

  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "environment must be one of: dev, staging, prod."
  }
}

variable "cidr_block" {
  description = "VPC CIDR block (RFC 1918)"
  type        = string

  validation {
    condition     = can(cidrhost(var.cidr_block, 0))
    error_message = "cidr_block must be a valid CIDR notation."
  }

  validation {
    condition     = can(regex("^(10|172|192)", var.cidr_block))
    error_message = "cidr_block should be RFC 1918 (10.x, 172.16-31.x, 192.168.x)."
  }
}

Numeric range

variable "instance_count" {
  description = "Number of instances"
  type        = number
  default     = 1

  validation {
    condition     = var.instance_count >= 1 && var.instance_count <= 100
    error_message = "instance_count must be between 1 and 100."
  }
}

variable "retention_days" {
  description = "Log retention in days"
  type        = number
  default     = 30

  validation {
    condition     = contains([1, 3, 5, 7, 14, 30, 60, 90, 180, 365, 400, 545, 731, 1827, 3653], var.retention_days)
    error_message = "retention_days must be a valid CloudWatch Logs retention period."
  }
}

Object type with optional fields

variable "database" {
  description = "Database configuration"
  type = object({
    engine          = string
    instance_class  = string
    allocated_storage = number
    multi_az        = optional(bool, false)
    backup_retention = optional(number, 7)
    deletion_protection = optional(bool, true)
    tags            = optional(map(string), {})
  })

  validation {
    condition     = contains(["mysql", "postgres", "mariadb"], var.database.engine)
    error_message = "database.engine must be mysql, postgres, or mariadb."
  }

  validation {
    condition     = var.database.allocated_storage >= 20 && var.database.allocated_storage <= 65536
    error_message = "database.allocated_storage must be between 20 and 65536 GB."
  }
}

List validation

variable "allowed_cidrs" {
  description = "List of allowed CIDR blocks"
  type        = list(string)
  default     = []

  validation {
    condition     = alltrue([for cidr in var.allowed_cidrs : can(cidrhost(cidr, 0))])
    error_message = "All entries in allowed_cidrs must be valid CIDR blocks."
  }

  validation {
    condition     = length(var.allowed_cidrs) <= 50
    error_message = "Maximum 50 CIDRs allowed (security group rule limit)."
  }
}

Map validation

variable "tags" {
  description = "Resource tags (must include required keys)"
  type        = map(string)
  default     = {}

  validation {
    condition = alltrue([
      for k in ["Environment", "Owner", "CostCenter"] : contains(keys(var.tags), k)
    ])
    error_message = "tags must include Environment, Owner, and CostCenter."
  }
}

Sensitive + nullable

variable "db_password" {
  description = "Database master password"
  type        = string
  sensitive   = true
  nullable    = false

  validation {
    condition     = length(var.db_password) >= 16
    error_message = "db_password must be at least 16 characters."
  }
}

variable "api_key" {
  description = "External API key"
  type        = string
  sensitive   = true
}

Cross-variable validation (via locals + check)

variable "min_size" { type = number }
variable "max_size" { type = number }

locals {
  size_validation = var.min_size <= var.max_size ? true : tobool("min_size must be <= max_size")
}

# Or use lifecycle precondition on a resource
resource "aws_autoscaling_group" "web" {
  min_size = var.min_size
  max_size = var.max_size

  lifecycle {
    precondition {
      condition     = var.min_size <= var.max_size
      error_message = "min_size must be less than or equal to max_size."
    }
  }
}

Common findings this catches

  • No validation → silent bad inputs.
  • Validation error message unclear → user confused.
  • Sensitive missing → secrets in plan output.
  • Default hides required input → use nullable: false.
  • Cross-variable check skipped → preconditions.
  • List validation iterates all → expensive at scale.
  • Optional vs nullable confusion → clarify intent.

When to escalate

  • Complex validation across modules — design.
  • Performance with large list inputs — profile.
  • Compliance requirements — strict typing.

Related prompts

Newsletter

Get weekly AI workflows for DevOps engineers

Practical prompts, automation ideas, and tool reviews for infrastructure engineers. One email per week. No spam.