Imagine youβre using Terraform to deploy infrastructure for three environments: dev
, staging
, and prod
. Each needs different resource names, tags, regions, etc., but the architecture is essentially the same.
Without variables, youβd end up duplicating code with minor edits. π΅βπ«
With variables, you get reusable, flexible, and DRY Terraform code.
Letβs dive into Terraform variables and learn how to use them right.
π‘ What Are Terraform Variables?
Terraform variables are placeholders that make your code dynamic. Instead of hardcoding values like region names or instance types, you define variables and reference them throughout your config.
π Terraform docs on variables, locals, and outputs
Supported variable types:
-
string
β text values -
number
β numeric values -
bool
βtrue
/false
-
list
β ordered collection -
map
β key-value pairs -
object
β structured types -
set
β unordered unique values
π¦ Example: Defining a Variable
variable "instance_type" {
description = "The type of EC2 instance to deploy"
type = string
default = "t2.micro"
}
π Referencing It in Your Code
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
}
π Using Variables in AWS Deployments
In real-world AWS deployments, Terraform variables help:
- Standardize naming
- Reuse infrastructure templates
- Maintain multi-environment setups
Want to see how a small team manages a massive AWS setup?
π How a global DevOps team of 5 manages 100K assets on AWS
For example, you can define variables for:
customer_name
environment
region
vpc_cidr
ami_id
π Working with Locals
Locals are used for internal calculations and derived values β they arenβt passed from the outside.
Use cases for locals:
- Shared
tags
- Constructed names
- Conditional values
locals {
common_tags = {
Customer = var.customer_name
Environment = var.environment
ManagedBy = "Terraform"
Project = "${var.customer_name}-${var.environment}"
}
name_prefix = "${var.customer_name}-${var.environment}"
is_production = var.environment == "prod"
instance_count = local.is_production ? 2 : 1
}
π§° Putting It All Together (Reusable Setup)
Step 1: Variables
variable "customer_name" { type = string }
variable "environment" { default = "dev" }
variable "aws_region" { default = "us-east-1" }
variable "vpc_cidr" { type = string }
variable "instance_type" { default = "t2.micro" }
variable "ami_id" { type = string }
Step 2: Locals
locals {
name_prefix = "${var.customer_name}-${var.environment}"
common_tags = {
Customer = var.customer_name
Environment = var.environment
ManagedBy = "Terraform"
Project = local.name_prefix
}
is_production = var.environment == "prod"
instance_count = local.is_production ? 2 : 1
}
Step 3β6: Provider, VPC, Subnet, EC2, S3, IAM
(Omitted here for brevity, see full example in previous block or include inline if desired)
π€ Terraform Outputs
output "vpc_id" {
value = aws_vpc.main.id
description = "The ID of the VPC"
}
output "instance_id" {
value = aws_instance.web.id
description = "The ID of the EC2 instance"
}
output "s3_bucket_name" {
value = aws_s3_bucket.data.bucket
description = "The name of the S3 bucket"
}
π Using .tfvars for Environment-Specific Configs
Instead of passing values via CLI each time, use .tfvars
files:
# customerA-dev.tfvars
customer_name = "controlmonkey"
aws_region = "us-east-1"
environment = "dev"
vpc_cidr = "10.2.0.0/16"
ami_id = "ami-084568db4383264d4"
Apply it with:
terraform apply -var-file="customerA-dev.tfvars"
You can version control these files too.
π The unsung hero of infrastructure management: version control
π§ Best Practices for Variables
- Group related variables logically
- Always include
description
fields - Use default values when sensible
- Validate variable inputs
- Use
.tfvars
for per-env overrides
variable "instance_type" {
type = string
default = "t2.micro"
validation {
condition = contains(["t2.micro", "t3.small", "t3.medium"], var.instance_type)
error_message = "Instance type must be t2.micro, t3.small, or t3.medium."
}
}
β οΈ Common Pitfalls to Avoid
- Overusing variables: not everything needs to be configurable
- Skipping locals: locals are great for intermediate values
- Ignoring sensitive data: mark credentials as sensitive
variable "database_password" {
description = "RDS database password"
type = string
sensitive = true
}
π§Ύ Conclusion
Terraform variables turn static code into dynamic, reusable, multi-environment infrastructure.
π Stay consistent
π Secure your inputs
π§ͺ Validate everything
π§Ό Keep it DRY
Want to go one step further?
π Detect configuration drift early
π§° Automate your deployments with ControlMonkey
π Explore the full resource library
[Originally Published - Terraform variables how to
](https://controlmonkey.io/resource/terraform-variables-guide/
)
π¬ How are you managing Terraform variables across teams and environments? Share your strategy below!
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.