When I first started writing Terraform code, I remember how confusing variables felt in the beginning. I had variable blocks everywhere some defined locally, some coming from outside, and I used to wonder which one takes priority and how Terraform actually decides the value. Over time, as I built real-world automation, I realized understanding variables is not just a Terraform concept it’s the foundation of writing clean, scalable, and reusable Infrastructure as Code.
Let’s take a simple Terraform setup to understand this better.
# variables.tf
variable "region" {
description = "AWS region where resources will be created"
type = string
default = "ap-south-1"
}
Here, the variable region is defined locally within the Terraform configuration. This is known as a local variable block because it’s defined and used within the same Terraform working directory. The default value makes sure Terraform still works even if you don’t explicitly pass the variable at runtime.
Now, let’s assume you want to override this region value without touching your code. This is where external variables come into play. Terraform allows you to pass variables externally through different methods for example, using .tfvars files, environment variables, or command line arguments.
Let’s say you have a terraform.tfvars file like this:
region = "us-east-1"
When you run terraform plan, Terraform will automatically pick up this external file and override the default value of region from “ap-south-1” to “us-east-1”. This is how external variable blocks help keep your infrastructure configuration reusable across different environments such as: dev, uat, or prod.
In one of my projects, we had to deploy EC2 instances in multiple regions using the same Terraform codebase. Instead of maintaining separate .tf files, I used external variable files such as dev.tfvars, uat.tfvars, and prod.tfvars, each containing specific configurations. With a simple command like:
terraform apply -var-file="prod.tfvars"
Terraform would automatically pick all the environment specific values from that file and build the infrastructure accordingly.
Now, there’s another layer to understand local variables (locals) in Terraform are not the same as variables defined in variables.tf. Locals are more like computed variables within your code. They help simplify expressions and avoid duplication. For example:
locals {
instance_name = "${var.env}-app-server"
}
Here, the local variable instance_name takes input from another variable env and generates a new value dynamically. You can use local.instance_name anywhere in your configuration for example, as the name tag of an EC2 instance.
So, in short, variables.tf defines configurable parameters that can be overridden externally, while locals define internal reusable expressions to simplify the code.
Here’s how both work together in a real world scenario:
# variables.tf
variable "env" {
type = string
description = "Environment name"
default = "dev"
}
# locals.tf
locals {
bucket_name = "my-${var.env}-bucket"
bucket_tags = {
Name = local.bucket_name
Environment = var.env
}
}
# main.tf
resource "aws_s3_bucket" "my_bucket" {
bucket = local.bucket_name
tags = local.bucket_tags
}
In this code example, I have also used a local variable block for bucket tags. This makes tag management simple and consistent across multiple resources. Instead of repeating tags in every resource block, defining them once inside locals ensures any change reflects everywhere. For instance, if I update the environment or bucket name, the tags automatically adjust. This approach keeps the code clean, modular, and easy to extend when you add more resources later.
As I mentioned above, If I apply this with a different environment using an external file like:
# prod.tfvars
env = "prod"
and run:
terraform apply -var-file="prod.tfvars"
Terraform will automatically create a bucket named “my-prod-bucket” with tags like Name = my-prod-bucket and Environment = prod. The same code, with different variable inputs, now works seamlessly across multiple environments.
That’s the real power of understanding the difference between local variables and external variables it helps make your Terraform code flexible, environment independent, and easy to maintain.
Over time, as you start managing larger infrastructure, this clarity helps you design cleaner modules, reuse components, and handle multiple environments without rewriting code. I’ve learned that writing Terraform isn’t about syntax it’s about designing logic that scales well.
So the next time you write a Terraform variable block, remember: Locals make your code simpler whereas external variables make it reusable.
![]()
- What Are Terraform Local and External Variables? Explained with Examples - November 11, 2025
- How to Deploy Docker Containers with NGINX on AWS EC2 Using Ansible and GitHub Actions - April 26, 2025
- No More DynamoDB! Use Native S3 locking for Terraform State - February 7, 2025
