Skip to main content
Terraform Input and Output Variables - Complete Guide

Terraform Input and Output Variables - Complete Guide

Key Takeaway

Master Terraform variables and outputs. Learn input variables, types, defaults, validation, sensitive values, output values, and variable files (tfvars).

Table of Contents

Quick Answer

Input variables parameterize your config. Output values expose results. Local values compute intermediate values. Define variables in variables.tf, set them in terraform.tfvars, and expose results in outputs.tf.

Input Variables

Basic Variable Types

# String
variable "environment" {
  type        = string
  description = "Deployment environment"
  default     = "dev"
}

# Number
variable "instance_count" {
  type    = number
  default = 2
}

# Boolean
variable "enable_monitoring" {
  type    = bool
  default = true
}

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

# Map
variable "instance_types" {
  type = map(string)
  default = {
    dev     = "t3.micro"
    staging = "t3.small"
    prod    = "t3.medium"
  }
}

# Object
variable "database" {
  type = object({
    engine         = string
    instance_class = string
    allocated_storage = number
  })
  default = {
    engine            = "postgres"
    instance_class    = "db.t3.micro"
    allocated_storage = 20
  }
}

Using Variables

resource "aws_instance" "web" {
  count         = var.instance_count
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_types[var.environment]

  tags = {
    Name        = "web-${var.environment}-${count.index}"
    Environment = var.environment
  }
}

Variable Validation

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

variable "instance_type" {
  type = string
  validation {
    condition     = can(regex("^t3\\.", var.instance_type))
    error_message = "Only t3.* instance types are allowed."
  }
}

Sensitive Variables

variable "db_password" {
  type      = string
  sensitive = true  # Won't show in plan output
}

Setting Variable Values

terraform.tfvars (Auto-loaded)

# terraform.tfvars
environment    = "prod"
instance_count = 3
enable_monitoring = true

Environment-Specific Files

# Apply with a specific var file
terraform apply -var-file="prod.tfvars"

Command Line

terraform apply -var="environment=prod" -var="instance_count=3"

Environment Variables

export TF_VAR_environment="prod"
export TF_VAR_db_password="secret123"
terraform apply

Precedence (Highest to Lowest)

  1. -var flag on command line
  2. *.auto.tfvars files (alphabetical order)
  3. terraform.tfvars
  4. Environment variables (TF_VAR_*)
  5. Variable defaults

Output Values

# outputs.tf
output "instance_ids" {
  description = "IDs of the web instances"
  value       = aws_instance.web[*].id
}

output "load_balancer_dns" {
  description = "DNS name of the load balancer"
  value       = aws_lb.main.dns_name
}

output "db_endpoint" {
  description = "Database connection endpoint"
  value       = aws_db_instance.main.endpoint
  sensitive   = true  # Hidden from console output
}
# View outputs after apply
terraform output
terraform output load_balancer_dns
terraform output -json  # Machine-readable

Local Values

locals {
  name_prefix = "${var.project}-${var.environment}"
  common_tags = {
    Project     = var.project
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_types[var.environment]
  tags          = merge(local.common_tags, { Name = "${local.name_prefix}-web" })
}

File Organization

project/
├── main.tf          # Resources
├── variables.tf     # Variable declarations
├── outputs.tf       # Output declarations
├── locals.tf        # Local values
├── terraform.tfvars # Default values
├── dev.tfvars       # Dev overrides
├── staging.tfvars   # Staging overrides
└── prod.tfvars      # Production overrides

Conclusion

Use input variables for parameterization, outputs to expose values to other configs, and locals for computed intermediate values. Always add type, description, and validation to variables. Use .tfvars files per environment and never hardcode secrets — use sensitive = true and environment variables.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.