By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For Cloud Engineers, DevOps, and Certification Prep)
Variables in Terraform are how you make your infrastructure code reusable, secure, and adaptable. Without them, you’d hardcode every value (e.g., instance_type = "t3.micro")—which means: - No environment separation (dev vs. prod would require duplicate code).- No secrets management (API keys, passwords, or DB credentials would leak in Git).- No flexibility (changing a single value would require editing every file).
instance_type = "t3.micro"
Real-world scenario:You’re deploying a multi-region AWS setup. Your dev environment uses t3.small instances, while prod needs m5.large. Without variables, you’d maintain two nearly identical Terraform configurations—a maintenance nightmare. With variables, you define the instance type once and override it per environment using .tfvars files.
dev
t3.small
prod
m5.large
.tfvars
What breaks if you ignore this?- Security breaches: Hardcoded secrets in Git.- Cost overruns: Accidentally deploying prod-sized resources in dev.- Failed audits: No traceability of who changed what (variables + .tfvars enable version-controlled config).
variable
description
terraform plan
hcl variable "instance_type" { type = string default = "t3.micro" description = "EC2 instance type for the web server" }
string
number
bool
"us-east-1"
"t3.micro"
42
0.01
true
false
enable_monitoring = true
desired_capacity = 2
"2"
list
map
["subnet-123", "subnet-456"]
{ dev = "t3.micro", prod = "m5.large" }
hcl variable "instance_types" { type = map(string) default = { dev = "t3.micro" prod = "m5.large" } }
sensitive
hcl variable "db_password" { type = string sensitive = true }
sensitive = true
dev.tfvars
prod.tfvars
.gitignore
# dev.tfvars instance_type = "t3.micro" db_password = "s3cr3t!" # ⚠️ Still bad—use a secrets manager!
terraform.tfvars
*.auto.tfvars
-var
terraform apply -var="instance_type=t3.large"
TF_VAR_instance_type=t3.large
locals
hcl locals { common_tags = { Environment = var.env Terraform = "true" } }
terraform -v
aws sts get-caller-identity
Deploy a dev and prod EC2 instance with different instance types using variables and .tfvars.
bash mkdir tf-variables-demo && cd tf-variables-demo
main.tf
provider "aws" { region = var.aws_region }
resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = var.instance_type tags = merge( local.common_tags, { Name = "${var.env}-web-server" } ) }
data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] } }
locals { common_tags = { Environment = var.env Terraform = "true" } } 3. Create `variables.tf`:hcl variable "aws_region" { type = string default = "us-east-1" description = "AWS region to deploy resources" }
3. Create `variables.tf`:
variable "instance_type" { type = string description = "EC2 instance type" }
variable "env" { type = string description = "Environment (dev/prod)" } ```
hcl aws_region = "us-east-1" instance_type = "t3.micro" env = "dev"
hcl aws_region = "us-east-1" instance_type = "m5.large" env = "prod"
bash terraform init
bash terraform plan -var-file="dev.tfvars"
t3.micro
bash terraform apply -var-file="dev.tfvars" -auto-approve
dev-web-server
bash terraform destroy -var-file="dev.tfvars" -auto-approve
bash terraform apply -var-file="prod.tfvars" -auto-approve
prod-web-server
terraform destroy -var-file="prod.tfvars" -auto-approve
*.tfvars
TF_VAR_db_password
db_instance_class
instance_type
validation
hcl variable "env" { type = string description = "Environment (dev/stage/prod)" validation { condition = contains(["dev", "stage", "prod"], var.env) error_message = "Environment must be dev, stage, or prod." } }
Environment
Terraform
terraform plan -out=tfplan && terraform show -json tfplan
-var-file
apply
desired_capacity = "2"
TF_VAR_*
Answer: A terraform.tfvars file is overriding the CLI flag (precedence issue).
Sensitive variables:
Answer: Set sensitive = true in the variable block.
Complex types:
list(string)
["us-east-1a", "us-east-1b"]
Challenge: Deploy an S3 bucket with a variable for the bucket name. Use a map to set different ACLs for dev (private) and prod (public-read). Test both environments.
Solution: 1. variables.tf: ```hcl variable "env" { type = string }
variables.tf
variable "bucket_acls" { type = map(string) default = { dev = "private" prod = "public-read" } } 2. `main.tf`:hcl resource "aws_s3_bucket" "demo" { bucket = "my-bucket-${var.env}" acl = var.bucket_acls[var.env] } 3. `dev.tfvars`:hcl env = "dev" 4. Deploy:bash terraform apply -var-file="dev.tfvars" ``` - Verify in AWS Console: The bucket should be private.
2. `main.tf`:
3. `dev.tfvars`:
4. Deploy:
Why it works: - The map (bucket_acls) lets you define environment-specific ACLs in one place.- var.bucket_acls[var.env] dynamically selects the ACL based on the environment.
bucket_acls
var.bucket_acls[var.env]
variable "instance_type" { type = string }
default = "t3.micro"
instance_type = var.instance_type
var.<name>
variable "subnets" { type = list(string) }
var.subnets[0]
variable "instance_types" { type = map(string) }
var.instance_types["dev"]
variable "db_password" { sensitive = true }
terraform apply -var-file="prod.tfvars"
export TF_VAR_instance_type=t3.large
validation { condition = contains(["dev", "prod"], var.env) }
locals { common_tags = { Terraform = "true" } }
us-east-1
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.