TerraformPilot

DevOps

Fix Terraform Error: No Value for Required Variable

Fix terraform required variable not set errors. Pass values via -var, terraform.tfvars, environment variables, or add defaults.

LLuca Berton1 min read

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)

#
  1. -var and -var-file on command line (highest)
  2. *.auto.tfvars files (alphabetical order)
  3. terraform.tfvars
  4. TF_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

#

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.

#Terraform#Troubleshooting#DevOps#Error Fix#Infrastructure as Code

Share this article