DEV Community

Cover image for 🧠 Your Guide to Terraform Variables
TerraformMonkey
TerraformMonkey

Posted on • Edited on • Originally published at controlmonkey.io

🧠 Your Guide to Terraform Variables

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"
}
Enter fullscreen mode Exit fullscreen mode

πŸ” Referencing It in Your Code

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = var.instance_type
}
Enter fullscreen mode Exit fullscreen mode

πŸš€ 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

Terraform AWS variable example


πŸ”‚ 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
}
Enter fullscreen mode Exit fullscreen mode

🧰 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 }
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

πŸ“ 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"
Enter fullscreen mode Exit fullscreen mode

Apply it with:

terraform apply -var-file="customerA-dev.tfvars"
Enter fullscreen mode Exit fullscreen mode

Folder structure with tfvars

You can version control these files too.

πŸ”— The unsung hero of infrastructure management: version control


🧠 Best Practices for Variables

  1. Group related variables logically
  2. Always include description fields
  3. Use default values when sensible
  4. Validate variable inputs
  5. 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."
  }
}
Enter fullscreen mode Exit fullscreen mode

⚠️ Common Pitfalls to Avoid

Terraform variable pitfalls

  • 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
}
Enter fullscreen mode Exit fullscreen mode

🧾 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.