Terraform Variables Making Configurations Flexible

Hard-coding values in Terraform configurations creates problems. Every time you need a different region, instance size, or environment name, you edit raw code. Variables solve this problem by separating the what (configuration logic) from the values (actual data). This topic covers input variable declaration, types, defaults, and the many ways to pass values in.

Why Variables Matter

Imagine writing a Terraform configuration for a web application. You deploy it to development, staging, and production. Without variables, you maintain three separate copies of the same code — each with different values hard-coded. With variables, you have one configuration and three values files.

Diagram: Variables Separate Logic from Data

WITHOUT variables:                WITH variables:
                                  
dev/main.tf                       main.tf          (shared logic)
  region = "us-east-1"              region = var.region
  size   = "t3.micro"               size   = var.instance_type
                                  
staging/main.tf                   dev.tfvars       (dev values)
  region = "us-east-1"              region         = "us-east-1"
  size   = "t3.medium"              instance_type  = "t3.micro"
                                  
prod/main.tf                      prod.tfvars      (prod values)
  region = "us-west-2"              region         = "us-west-2"
  size   = "t3.large"               instance_type  = "t3.large"

Declaring an Input Variable

You declare variables in a variable block, typically in a file called variables.tf.

variable "instance_type" {
  description = "The EC2 instance size to use"
  type        = string
  default     = "t3.micro"
}

The Three Common Arguments

  • description: Explains what this variable is for. Always include it — it appears in documentation and error messages.
  • type: Tells Terraform what kind of value is expected. Terraform rejects wrong types with a clear error.
  • default: A fallback value used when no value is provided. If you omit default, the variable becomes required.

Variable Types

TypeExample ValueUse Case
string"us-east-1"Region names, resource names, AMI IDs
number3Port numbers, replica counts, disk size
booltrueFeature toggles, enable/disable flags
list(string)["a", "b", "c"]Lists of subnet IDs, availability zones
map(string){ key = "val" }Tags, environment-specific key-value pairs
object({...})Complex structured dataGrouped configurations

Using a Variable

Reference a variable with the var. prefix followed by the variable name.

resource "aws_instance" "app" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = var.instance_type
}

Ways to Pass Variable Values

Terraform checks several places for variable values, in this order of precedence (lowest to highest):

  1. Default value in the variable block
  2. A .tfvars file (auto-loaded if named terraform.tfvars)
  3. A .tfvars file passed with -var-file flag
  4. Command-line -var flag
  5. Environment variable prefixed with TF_VAR_

Method 1: terraform.tfvars File

Create a file named terraform.tfvars in the same directory. Terraform loads it automatically.

instance_type = "t3.medium"
region        = "us-west-2"

Method 2: Named .tfvars File

terraform apply -var-file="production.tfvars"

Method 3: Command-Line Flag

terraform apply -var="instance_type=t3.large"

Method 4: Environment Variable

export TF_VAR_instance_type="t3.large"
terraform apply

Environment variables are popular in CI/CD pipelines where you cannot write files to the runner's disk.

Variable Validation Rules

You can enforce rules on variable values using a validation block. This catches bad inputs early — before Terraform tries to contact a cloud provider.

variable "environment" {
  type        = string
  description = "Deployment environment"

  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be dev, staging, or prod."
  }
}

If someone passes environment = "production", Terraform stops immediately and shows the custom error message — saving time and preventing accidental bad deployments.

Key Points

  • Variables separate configuration logic from the values that change per environment or deployment.
  • Declare variables with a variable block; always include a description and type.
  • Reference variables in your resources using var.variable_name.
  • Terraform loads terraform.tfvars automatically; use -var-file for other tfvars files.
  • Use validation blocks to reject bad inputs immediately with clear, readable error messages.

Leave a Comment