In this Day 05 demo, I explore how Terraform variables work by creating a simple AWS EC2 isntance, S3 bucket and VPC. Terraform has three main types of variables: input variables, local variables, and output variables. We'll define each type, see how they are used, and observe their values in a Terraform run.
π― Three Types of Variables
Terraform supports three key variable types:
Input Variables (variables.tf)
Input variables are values you provide to Terraform (like function parameters). They allow you to customize your Terraform configuration without hardcoding values. You define them in variables.tf. For example:
variable "environment" {
description = "Environment name"
type = string
default = "staging"
}
Local Variables (locals.tf)
Local variables are internal, computed values used within a Terraform module (like local variables in a programming language). They help you avoid repeating expressions. They are defined in locals.tf. For example:
locals {
common_tags = {
Environment = var.environment
Project = "Terraform-Demo"
Owner = "DevOps-Team"
}
# full bucket name with environment prefix
full_bucket_name = "${var.environment}-${var.bucket_name}-${random_string.suffix.result}"
}
Output Variables (output.tf)
Output variables are values returned after Terraform runs (like function return values). They let you expose useful information about your infrastructure. Define them in output.tf. For example:
output "bucket_name" {
description = "Name of the S3 bucket"
value = aws_s3_bucket.demo.bucket
}
π₯ Understanding Input Variables in Detail
What are Input Variables?
Input variables act like function parameters in Terraform. They enable you to parameterize your configuration and pass in different values each time you run Terraform, making your code more flexible and reusable.
Basic Input Variable Structure:
Hereβs the general structure of an input variable in Terraform:
variable "variable_name" {
description = "What this variable is for"
type = string
default = "default_value" # Optional default value
}
This defines a variable called variable_name, with a type and an optional default value.
How to Use Input Variables
You define input variables in variables.tf, then use them with the var. prefix in your resources. For example, define environment and bucket_name variables:
variable "region" {
description = "AWS Region"
type = string
}
variable "environment" {
description = "Environment name like dev, stage, prod"
type = string
}
variable "ami_id" {
description = "AMI ID for the ec2 instance"
type = string
}
variable "instance_type" {
description ="EC2 instance type"
type = string
}
variable "bucket_name" {
description = "S3 Bucket name"
type = string
}
variable "vpc_cidr_block" {
description = "CIDR block for the VPC"
type = string
}
Then in your main.tf, reference them when creating an S3 bucket:
resource "aws_instance" "my_instance" {
ami = var.ami_id
instance_type = var.instance_type
tags = local.common_tags
}
resource "aws_s3_bucket" "terraform_bucket" {
bucket = local.full_bucket_name
tags = local.common_tags
}
resource "aws_vpc" "terraform_vpc" {
cidr_block = var.vpc_cidr_block
tags = local.common_tags
}
Here var.bucket_name and var.environment use the values from our input variables.
Providing Values to Input Variables
Terraform allows several ways to set variable values. They are applied in order of precedence (last one wins):
- Default values (in
variables.tf): You can set a default in the variable block itself. For example:
variable "environment" {
default = "staging"
}
-
terraform.tfvarsfile (auto-loaded): Create a file namedterraform.tfvars(or*.auto.tfvars) with variable values:
environment = "demo"
bucket_name = "terraform-demo-bucket"
- Command-line flags: Override variables during commands. For example:
terraform plan -var="environment=production"
- Environment variables: Use TF_VAR_ prefix for each variable. For example:
export TF_VAR_environment="development"
terraform plan
Values are applied with this precedence: defaults < terraform.tfvars < environment variables < command-line flags.
π€ Understanding Output Variables in Detail
What are Output Variables?
Output variables are like function return values. They let Terraform display important information about your infrastructure after creation, such as resource IDs, ARNs, or computed values. You declare output variables in output.tf.
Basic Output Variable Structure:
A typical output variable looks like this:
output "output_name" {
description = "What this output shows"
value = aws_s3_bucket.demo.arn
}
It names the output and specifies which value to return.
How to Use Output Variables
Define outputs in output.tf to expose values. For example, to output our S3 bucket details:
output "bucket_name" {
description = "Name of the S3 bucket"
value = aws_s3_bucket.demo.bucket
}
output "bucket_arn" {
description = "ARN of the S3 bucket"
value = aws_s3_bucket.demo.arn
}
output "environment" {
description = "Environment from input variable"
value = var.environment
}
output "tags" {
description = "Tags from local variable"
value = local.common_tags
}
After running terraform apply, you can see these outputs:
terraform output # Show all outputs
terraform output bucket_name # Show specific output
terraform output -json # Show outputs in JSON format
Example output:
This output confirms the values of the variables and attributes after deployment.
ποΈ What This Creates
This example creates a single S3 bucket that demonstrates all three variable types:
- Uses input variables for setting the environment and base bucket name.
- Uses local variables to compute a unique bucket name and apply common tags.
- Uses output variables to display the bucket details after creation.
π Variable Precedence Testing
Terraform applies variable values by precedence. You can test how different sources are picked:
- Default Values (without
terraform.tfvars): Temporarily hideterraform.tfvarsto use defaults.
mv terraform.tfvars terraform.tfvars.backup
terraform plan
# Uses: environment = "staging" (from variables.tf default)
mv terraform.tfvars.backup terraform.tfvars # restore
- With
terraform.tfvars(auto-loaded): Run normally with the tfvars file present.
terraform plan
# Uses: environment = "demo" (from terraform.tfvars)
- Command-Line Override (highest precedence): Override a value on the command line.
terraform plan -var="environment=production"
Overrides: environment = "production"
- Environment Variables: Export a TF_VAR_ variable.
export TF_VAR_environment="staging-from-env"
terraform plan
# Uses: environment = "staging-from-env" (unless `-var` is used)
- Different tfvars Files: Specify a different tfvars file for an environment.
terraform plan -var-file="dev.tfvars" # environment = "development"
terraform plan -var-file="production.tfvars" # environment = "production"
Each test shows which value Terraform picks according to the precedence rules.
π Simple File Structure
A simple file layout for this example might look like:
βββ main.tf # S3 bucket resource
βββ variables.tf # Input variables (environment, bucket_name)
βββ locals.tf # Local variables (tags, computed bucket name)
βββ output.tf # Output variables (bucket details)
βββ provider.tf # AWS provider configuration
βββ terraform.tfvars # Default variable values
βββ README.md # Project description
π§ͺ Practical Examples
Example 1: Testing Different Input Values
# Test with defaults (temporarily hide terraform.tfvars)
mv terraform.tfvars terraform.tfvars.backup
terraform plan
# Shows: Environment = "staging", bucket will be "staging-my-terraform-bucket-xxxxx"
# Test with terraform.tfvars
mv terraform.tfvars.backup terraform.tfvars
terraform plan
# Shows: Environment = "demo", bucket will be "demo-terraform-demo-bucket-xxxxx"
# Test with command-line override
terraform plan -var="environment=test" -var="bucket_name=my-test-bucket"
# Shows: Environment = "test", bucket will be "test-my-test-bucket-xxxxx"
Example 2: Viewing All Variable Types in Action
# Apply the configuration and output resources
terraform apply -auto-approve
# Show all outputs (output variables)
terraform output
# bucket_arn = "arn:aws:s3:::demo-terraform-demo-bucket-abc123"
# bucket_name = "demo-terraform-demo-bucket-abc123"
# environment = "demo"
# tags = {
# "Environment" = "demo"
# "Owner" = "DevOps-Team"
# "Project" = "Terraform-Demo"
# }
# Check the individual values with echo:
echo "Input: environment = $(terraform output -raw environment)"
echo "Input: bucket_name = terraform-demo-bucket (from tfvars)"
echo "Local: full_bucket_name = $(terraform output -raw bucket_name)"
echo "Random suffix was added by the local variable!"
π§ Try These Commands
terraform init
terraform plan
terraform plan -var="environment=test"
terraform plan -var-file="dev.tfvars"
terraform apply -auto-approve
terraform output
terraform destroy
π Connect With Me
If you enjoyed this post or want to follow my #30DaysOfAWSTerraformChallenge journey, feel free to connect with me here:
πΌ LinkedIn: Amit Kushwaha
π GitHub: Amit Kushwaha
π Hashnode / Amit Kushwaha
π¦ Twitter/X: Amit Kushwaha






Top comments (0)