Quick Answer
# Option 1: Pass on command line
terraform apply -var="instance_type=t3.micro"
# Option 2: Create terraform.tfvars
echo 'instance_type = "t3.micro"' > terraform.tfvars
terraform apply
# Option 3: Environment variable
export TF_VAR_instance_type="t3.micro"
terraform apply
The Error
Error: No value for required variable
on variables.tf line 1:
1: variable "instance_type" {
The root module input variable "instance_type" is not set, and has no
default value. Use a -var or -var-file command line argument or set a
TF_VAR_ environment variable to provide a value for this variable.
What Causes This
A variable declared without a default was not provided:
# This REQUIRES a value (no default)
variable "instance_type" {
type = string
description = "EC2 instance type"
}
# This does NOT require a value (has default)
variable "region" {
type = string
default = "us-east-1"
}
All Ways to Set Variables
1. terraform.tfvars (Auto-Loaded)
# terraform.tfvars — loaded automatically
instance_type = "t3.micro"
environment = "production"
vpc_cidr = "10.0.0.0/16"
2. Named .tfvars File
# prod.tfvars
instance_type = "t3.large"
environment = "production"
terraform apply -var-file="prod.tfvars"
3. Command Line -var
terraform apply -var="instance_type=t3.micro" -var="environment=dev"
4. Environment Variables
# Prefix with TF_VAR_
export TF_VAR_instance_type="t3.micro"
export TF_VAR_environment="dev"
terraform apply
5. Add a Default Value
variable "instance_type" {
type = string
default = "t3.micro" # Now it's optional
}
Variable Precedence (Highest Wins)
-varand-var-fileon command line (highest)*.auto.tfvarsfiles (alphabetical order)terraform.tfvarsTF_VAR_environment variables (lowest)
# -var overrides everything
export TF_VAR_instance_type="t3.micro"
# terraform.tfvars has: instance_type = "t3.small"
terraform apply -var="instance_type=t3.large"
# Result: t3.large (command line wins)
CI/CD Patterns
GitLab CI
variables:
TF_VAR_environment: $CI_ENVIRONMENT_NAME
TF_VAR_instance_type: "t3.micro"
deploy:
script:
- terraform apply -auto-approve -var-file="${CI_ENVIRONMENT_NAME}.tfvars"
Per-Environment tfvars
├── main.tf
├── variables.tf
├── dev.tfvars
├── staging.tfvars
└── prod.tfvars
terraform apply -var-file="dev.tfvars"
terraform apply -var-file="prod.tfvars"
Complex Variable Types
# terraform.tfvars
tags = {
Environment = "prod"
Team = "platform"
}
allowed_cidrs = ["10.0.0.0/8", "172.16.0.0/12"]
database = {
engine = "postgres"
instance_class = "db.t3.medium"
storage = 100
}
Via environment variable (JSON):
export TF_VAR_tags='{"Environment":"prod","Team":"platform"}'
export TF_VAR_allowed_cidrs='["10.0.0.0/8","172.16.0.0/12"]'
Sensitive Variables
variable "db_password" {
type = string
sensitive = true # Won't show in plan output
}
# Best: environment variable (doesn't appear in shell history with some shells)
export TF_VAR_db_password="secret123"
# OK: var file (don't commit to Git)
echo 'db_password = "secret123"' > secrets.tfvars
echo "secrets.tfvars" >> .gitignore
terraform apply -var-file="secrets.tfvars"
Hands-On Courses
- Terraform for Beginners on CopyPasteLearn
- Terraform By Example — practical code examples
Conclusion
Required variables need a value from somewhere: -var, .tfvars, or TF_VAR_ environment variable. Use terraform.tfvars for defaults, per-environment .tfvars files for multi-env setups, and TF_VAR_ for secrets in CI/CD. Add default to make variables optional.