TerraformPilot

Terraform

Terraform Input and Output Variables - Complete Guide

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

LLuca Berton1 min read

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.

#Terraform#DevOps#Infrastructure as Code

Share this article