LAB24_GCP_Terraform Core: Advanced Input Variables and Custom Validation

Terraform Core: Advanced Input Variables and Custom Validation

☁ GCP 🟢 Beginner Terraform Core HCL Variables Validation

Scenario

You are writing a Terraform configuration that will be used by other developers. They need to supply an environment name and an instance size. If they supply a machine type that is too expensive (e.g., n2-standard-32), or an environment name outside of the approved list ("dev", "staging", "prod"), the deployment should fail before calling any GCP APIs. You enforce this using Variable Validation.

Your Objectives
  • Define a variable environment. Add a validation block that ensures the string is either dev, staging, or prod.
  • Define a variable machine_type and add a validation block that uses regex to ensure it starts with e2-.
  • Pass these variables into a simple google_compute_instance resource.

Additional Context

Variable validations run at plan time, making them a "shift-left" security check. The deployment fails almost instantly if the user provides bad inputs, saving time and preventing misconfiguration.

The condition argument inside a validation block must evaluate to a boolean. You can use any standard Terraform functions here, like contains(), length(), and can(regex()).

variables.tf

variable "project_id" { type = string }
variable "gcp_zone"   { type = string; default = "us-central1-a" }

variable "environment" {
  type        = string
  description = "The target deployment environment."
  
  # Custom Validation Rule 1: Array inclusion
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "The environment must be 'dev', 'staging', or 'prod'."
  }
}

variable "machine_type" {
  type        = string
  description = "Compute Engine machine type."
  default     = "e2-micro"
  
  # Custom Validation Rule 2: Regex matching
  validation {
    condition     = can(regex("^e2-.*", var.machine_type))
    error_message = "For budget reasons, only e2 machine types (e.g., e2-micro, e2-medium) are permitted."
  }
}

main.tf

provider "google" {
  project = var.project_id
  zone    = var.gcp_zone
}

resource "google_compute_instance" "app" {
  name         = "app-server-${var.environment}"
  machine_type = var.machine_type

  boot_disk {
    initialize_params { image = "debian-cloud/debian-11" }
  }

  network_interface {
    network = "default"
  }

  labels = {
    environment = var.environment
  }
}

Workflow Commands

terraform init

# This will succeed (vars meet validation conditions)
terraform apply -var="project_id=my-gcp-project-123" \
  -var="environment=dev" \
  -var="machine_type=e2-small"

# TEST: This will fail immediately at Plan phase due to bad environment
terraform plan -var="project_id=my-gcp-project-123" \
  -var="environment=QA" 

# TEST: This will fail immediately due to bad regex match
terraform plan -var="project_id=my-gcp-project-123" \
  -var="environment=prod" \
  -var="machine_type=n2-standard-4"

terraform destroy -var="project_id=my-gcp-project-123" -var="environment=dev"
✓ Expected Output For Bad Input
Error: Invalid value for variable

  on variables.tf line 4:
   4: variable "environment" {

The environment must be 'dev', 'staging', or 'prod'.