In the last blog, we created our first Terraform project with a hardcoded AWS S3 bucket name. But in real-world projects, hardcoding values becomes a nightmare.
Imagine changing the region or bucket name across 20 files manually sounds painful, right?
This is where Variables & Outputs make Terraform configurations flexible, reusable, and production-ready.
Why Variables?
Variables in Terraform let you:
- Reuse the same code for multiple environments (dev, staging, prod).
- Avoid duplication of values across files.
- Parameterize deployments for flexibility.
Defining Variables
Let’s create a new file called variables.tf
:
variable "region" {
description = "The AWS region to deploy resources"
type = string
default = "us-east-1"
}
variable "bucket_name" {
description = "Name of the S3 bucket"
type = string
}
How to use variables in main.tf
provider "aws" {
region = var.region
}
resource "aws_s3_bucket" "my_bucket" {
bucket = var.bucket_name
acl = "private"
}
Passing Variable Values
You can pass values in three ways:
- Default values in
variables.tf
(used automatically). - Command-line arguments: terraform apply -var="bucket_name=my-dynamic-bucket"
terraform.tfvars
file: bucket_name = "my-dynamic-bucket"
Terraform automatically picks up terraform.tfvars
.
Why Outputs?
Outputs in Terraform let you export information about created resources.
For example, after creating an S3 bucket, you may want the bucket’s ARN or name for another project.
Defining Outputs
Create a file called outputs.tf
:
output "bucket_arn" {
description = "The ARN of the S3 bucket"
value = aws_s3_bucket.my_bucket.arn
}
output "bucket_name" {
description = "The name of the S3 bucket"
value = aws_s3_bucket.my_bucket.bucket
}
When you run:
terraform apply
Terraform will display the bucket name and ARN after creation.
Case Study: Multi-Environment Setup
A fintech company used Terraform to manage AWS infrastructure for:
- Development (smaller instances)
- Staging (near-production)
- Production (high availability)
Instead of maintaining 3 separate codebases, they used:
- Variables to control instance sizes, regions, and resource names.
- Outputs to share database URLs and load balancer endpoints across teams.
Result? One reusable codebase, fewer mistakes, and faster deployments.
Best Practices for Variables & Outputs
- Use
terraform.tfvars
for environment-specific values. - Never store secrets in variables. Use AWS Secrets Manager or Vault instead.
- Group variables logically for better readability.
- Use outputs only when needed—avoid leaking sensitive data.
Example Project Structure
terraform-project/
├── main.tf
├── variables.tf
├── outputs.tf
└── terraform.tfvars
What’s Next?
Now we have:
- Dynamic variables for flexibility
- Outputs for sharing resource details
Bibliography
- HashiCorp. Terraform Providers Documentation. Available at: https://developer.hashicorp.com/terraform/language/providersAmazon Web Services. AWS Terraform Provider Docs. Available at: https://registry.terraform.io/providers/hashicorp/aws/latest/docs
- Microsoft Azure. Azure Terraform Provider Docs. Available at: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
- Google Cloud Platform. GCP Terraform Provider Docs. Available at: https://registry.terraform.io/providers/hashicorp/google/latest/docs
- HashiCorp. Terraform Meta-Arguments: count and for_each. Available at: https://developer.hashicorp.com/terraform/language/meta-arguments