Hardcoding values in Terraform files works… until it doesn’t. The moment you need different configurations for staging, production, or even per-developer setups, things start getting messy fast.
This is where setting Terraform variables using a file becomes essential. Instead of embedding values directly in your code, you externalize them into dedicated files like .tfvars or JSON files. It keeps your configuration clean, reusable, and far easier to manage.
Start with a Simple Variable
Before jumping into files, here’s a basic variable definition:
1variable "instance_type" {
2 description = "EC2 instance type"
3 type = string
4}Without a value, Terraform will prompt for one at runtime. That’s fine for quick tests, but not for real workflows.
Using a .tfvars File
The most common way to set variables is with a .tfvars file.
Create a file named terraform.tfvars:
1instance_type = "t3.micro"Terraform automatically loads this file if it’s named exactly terraform.tfvars or *.auto.tfvars.
Now running:
1terraform planwill pick up the value without prompting.
Custom Variable Files
You’re not limited to the default name. For environment-specific configs, try:
1dev.tfvars
2prod.tfvarsThen pass them explicitly:
1terraform apply -var-file="dev.tfvars"This pattern is widely used in CI/CD pipelines.
JSON Variable Files (Less Talked About, Very Useful)
Terraform also supports JSON for variables, which is handy when integrating with external systems.
Example variables.json:
1{
2 "instance_type": "t3.small",
3 "region": "us-east-1"
4}Apply it like this:
1terraform apply -var-file="variables.json"JSON becomes especially useful when generating configs dynamically from scripts or APIs.
Let’s Wire It Into a Real Example
Here’s a minimal AWS setup using variables from a file:
1variable "region" {
2 type = string
3}
4
5variable "instance_type" {
6 type = string
7}
8
9provider "aws" {
10 region = var.region
11}
12
13resource "aws_instance" "example" {
14 ami = "ami-0c55b159cbfafe1f0"
15 instance_type = var.instance_type
16}And your prod.tfvars:
1region = "us-west-2"
2instance_type = "t3.medium"Run:
1terraform apply -var-file="prod.tfvars"Same code, different infrastructure behavior. That’s the real power here.
A Few Gotchas Worth Knowing
A common mistake developers make is assuming Terraform loads all .tfvars files automatically. It doesn’t.
- Auto-loaded: terraform.tfvars, *.auto.tfvars
- Manual: anything else requires -var-file
Another subtle issue: variable precedence. If the same variable is defined in multiple places, Terraform resolves them in a specific order:
- CLI flags (-var, -var-file)
- Environment variables
- Auto-loaded tfvars files
- Default values in code
If something feels “ignored,” it’s usually a precedence issue.
When to Use Which Approach
Not all variable files are equal. Here’s how they typically fit:
- terraform.tfvars → Local defaults for development
- env-specific tfvars → dev/staging/prod separation
- JSON files → Generated configs or integrations
If you’re working in a team, splitting variables by environment is almost non-negotiable.
Handling Sensitive Data
Don’t put secrets directly into tfvars files that live in version control.
Better options:
- Use environment variables (e.g.,
TF_VAR_db_password) - Integrate with secret managers (AWS Secrets Manager, Vault)
- Use Terraform Cloud variable sets
Even though Terraform supports sensitive = true, that only affects output display—not storage security.
Performance and Workflow Considerations
Variable files don’t directly impact Terraform performance, but they do affect workflow clarity.
Clean separation of variables:
- Reduces accidental changes
- Makes plans easier to review
- Simplifies automation
In CI/CD pipelines, passing explicit -var-file flags ensures predictable deployments.
A Practical Pattern That Scales
Here’s a structure that works well in real projects:
1terraform/
2 main.tf
3 variables.tf
4 outputs.tf
5 env/
6 dev.tfvars
7 staging.tfvars
8 prod.tfvarsThen your pipeline or CLI selects the environment explicitly. No guessing, no surprises.
Wrapping It Up
Setting a variable using a file in Terraform isn’t just a convenience—it’s a foundational practice for maintainable infrastructure.
Whether you use .tfvars or JSON, the goal is the same: keep your code generic and your configuration flexible. Once you adopt this pattern, switching environments or scaling your setup becomes dramatically easier.
And if something behaves unexpectedly, check your variable sources first. That’s almost always where the story begins.