The Scenario
Imagine it is 2 AM. You are pushing a hotfix to scale a production database from a t3.medium to an m5.large. You update your terraform.tfvars file with the new instance size, hit save, and run terraform plan. Instead of a smooth rollout, the terminal spits back a wall of red text:
Error: Value for undeclared variable
The root module does not declare a variable named "instance_size" but a value was
assigned to it in terraform.tfvars. To declare variable "instance_size", place this
block in one of your .tf files:
variable "instance_size" {
type = string
}
Terraform is strictly typed and requires explicit declarations. Unlike dynamic languages where you can pass arbitrary key-value pairs, Terraform demands a matching variable block for every value in your .tfvars file or -var flag. If the blueprint doesn't expect the data, Terraform refuses to process it.
Why Terraform is Complaining
During the initialization phase, Terraform automatically loads every .tfvars file in your current directory. When it encounters a key like max_db_connections = 100, it immediately scans your .tf files for a corresponding variable "max_db_connections" {} block. If that definition is missing, the process halts to prevent misspelled or orphaned configuration data from polluting your state.
Common triggers for this error include:
- The Forgotten Block: You defined the value in
terraform.tfvarsbut skipped thevariabledeclaration invariables.tf. - Typos: A simple slip-up, such as writing
instane_typein one file andinstance_typein another. - Case Sensitivity: Terraform treats
Database_Nameanddatabase_nameas two completely different entities. - Root vs. Child Modules: You might be trying to set a variable for a child module directly from the root
.tfvarsfile, which Terraform does not allow.
The Quick Fix
To get your deployment back on track, identify the variable name from the error message. Then, add a declaration block to your variables.tf file or any other .tf file in your root directory.
# variables.tf
variable "instance_size" {
description = "The EC2 instance type, e.g., m5.large"
type = string
}
Once you save this block, Terraform will recognize the value assigned in your variables file and proceed with the plan.
Best Practices for a Cleaner Config
Don't let variable mismatches slow down your CI/CD pipeline. Use these strategies to keep your code in sync.
1. Maintain a 1:1 Mapping
Every entry in your .tfvars file should have a twin in variables.tf. If you deprecate a setting—for example, moving from 10 to 20 subnets—remember to delete the unused variable from both files. Dead code leads to confusion during audits.
2. Pass Variables to Modules Correctly
You cannot inject values directly into a child module from the root terraform.tfvars. Instead, you must declare the variable in the root, then explicitly pass it to the module block.
# root/variables.tf
variable "app_port" { type = number }
# root/main.tf
module "web_server" {
source = "./modules/web"
port = var.app_port
}
3. Validate Early and Often
Run terraform validate as part of your local workflow or pre-commit hook. This command is fast. It catches undeclared variables in seconds without needing to check your cloud provider or refresh your state file.
4. Check Your Environment Variables
Sometimes the culprit isn't a file. Terraform also looks for shell variables prefixed with TF_VAR_. If you have export TF_VAR_api_key="12345" set in your terminal or Jenkins agent, Terraform expects to find a variable "api_key" {} block in your code.
Verification
Confirm the fix by running a targeted plan. If the declaration is correct, the red error text will be replaced by a standard execution plan.
terraform plan -out=tfplan
A successful fix will result in a "No changes" message or a list of intended infrastructure updates. If the error is gone, your assignments and declarations are finally in sync.
Summary for the 2 AM Troubleshooter
- Grab the variable name from the error message.
- Search your
.tffiles forvariable "name_here". - If it's missing, add the block to
variables.tf. - Check for typos or
UPPERCASEvslowercasemismatches. - Run
terraform validateto confirm the fix.

