Table of Contents

Introduction

Terraform variables are the foundation of reusable, maintainable infrastructure code. Whether you’re managing a single environment or orchestrating multi-cloud deployments, understanding variables is essential.

This comprehensive guide covers every type of Terraform variable with real-world examples you can use immediately.

Input Variables

Input variables let you parameterize your Terraform configurations. They make your code reusable across environments.

Declaring Variables

variable "region" {
  description = "AWS region for resources"
  type        = string
  default     = "us-east-1"
}

variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t3.micro"
  
  validation {
    condition     = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
    error_message = "Instance type must be t3.micro, t3.small, or t3.medium."
  }
}

Variable Types

Terraform supports several variable types:

  • string - Single text value
  • number - Numeric value
  • bool - True or false
  • list - Ordered collection
  • map - Key-value pairs
  • object - Structured data with named attributes
  • tuple - Ordered collection with specific types per element
variable "tags" {
  type = map(string)
  default = {
    Environment = "dev"
    Project     = "terraform-demo"
  }
}

variable "availability_zones" {
  type    = list(string)
  default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}

variable "server_config" {
  type = object({
    name          = string
    instance_type = string
    disk_size     = number
    monitoring    = bool
  })
}

Setting Variable Values

There are multiple ways to set variable values:

  1. Command line: terraform apply -var="region=us-west-2"
  2. Variable files: Create terraform.tfvars or *.auto.tfvars
  3. Environment variables: export TF_VAR_region=us-west-2
  4. Interactive prompt: Terraform asks for values without defaults

terraform.tfvars

region        = "us-west-2"
instance_type = "t3.small"
tags = {
  Environment = "production"
  Team        = "platform"
}

Environment-specific files

terraform apply -var-file="environments/prod.tfvars"

Output Variables

Output variables expose values from your Terraform configuration. They’re essential for module composition and debugging.

output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.web.id
}

output "public_ip" {
  description = "Public IP address"
  value       = aws_instance.web.public_ip
}

output "database_password" {
  description = "Database password"
  value       = aws_db_instance.main.password
  sensitive   = true
}

Access outputs after apply:

terraform output instance_id
terraform output -json

Local Variables

Local variables simplify complex expressions and avoid repetition:

locals {
  common_tags = {
    Project     = var.project_name
    Environment = var.environment
    ManagedBy   = "terraform"
    Owner       = var.team
  }
  
  name_prefix = "${var.project_name}-${var.environment}"
  
  is_production = var.environment == "production"
}

resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = local.is_production ? "t3.large" : "t3.micro"
  
  tags = merge(local.common_tags, {
    Name = "${local.name_prefix}-web"
  })
}

Variable Validation

Add custom validation rules to catch errors early:

variable "environment" {
  type = string
  
  validation {
    condition     = contains(["dev", "staging", "production"], var.environment)
    error_message = "Environment must be dev, staging, or production."
  }
}

variable "cidr_block" {
  type = string
  
  validation {
    condition     = can(cidrhost(var.cidr_block, 0))
    error_message = "Must be a valid CIDR block."
  }
}

Sensitive Variables

Mark variables as sensitive to prevent them from appearing in logs:

variable "db_password" {
  type      = string
  sensitive = true
}

Best Practices

  1. Always add descriptions to variables
  2. Use validation blocks for input constraints
  3. Group related variables in separate files
  4. Use locals for computed values and DRY code
  5. Mark sensitive data with sensitive = true
  6. Use consistent naming conventions across modules
  7. Provide sensible defaults where appropriate
  8. Document required variables without defaults

Hands-On Courses

Take your Terraform skills further with structured learning:

Conclusion

Terraform variables are powerful tools for creating flexible, reusable infrastructure code. By mastering input, output, local, and sensitive variables, you can build configurations that scale across teams and environments.

Start applying these patterns in your next Terraform project and see how much cleaner your code becomes.