Jump to content

Welcome to CodeNameJessica

✨ Welcome to CodeNameJessica! ✨

πŸ’» Where tech meets community.

Hello, Guest! πŸ‘‹
You're just a few clicks away from joining an exclusive space for tech enthusiasts, problem-solvers, and lifelong learners like you.

πŸ” Why Join?
By becoming a member of CodeNameJessica, you’ll get access to:
βœ… In-depth discussions on Linux, Security, Server Administration, Programming, and more
βœ… Exclusive resources, tools, and scripts for IT professionals
βœ… A supportive community of like-minded individuals to share ideas, solve problems, and learn together
βœ… Project showcases, guides, and tutorials from our members
βœ… Personalized profiles and direct messaging to collaborate with other techies

🌐 Sign Up Now and Unlock Full Access!
As a guest, you're seeing just a glimpse of what we offer. Don't miss out on the complete experience! Create a free account today and start exploring everything CodeNameJessica has to offer.

Chapter 3: Terraform Variables and Locals

(0 reviews)
by: Akhilesh Mishra
Fri, 28 Nov 2025 15:35:51 +0530


Chapter 3: Terraform Variables and Locals

Basic Variable Types

Terraform has three basic types: string, number, and bool.

variable "name" {
type = string
description = "User name"
default = "World"
}
variable "counts" {
type = number
default = 5
}
variable "enabled" {
type = bool
default = true
}

Use them:

resource "local_file" "example" {
content = "Hello, ${var.name}! Count: ${var.counts}, Enabled: ${var.enabled}"
filename = "output.txt"
}
🚧
You cannot use reserved words like count as variable name.

Change values:

terraform apply -var="name=Alice" -var="counts=10"
Apply Variable and other values in Terraform.
Apply Variable

Always add description. Future you will thank you.

Advanced Variable Types

Real infrastructure needs complex data structures.

Lists

Ordered collections of values:

variable "availability_zones" {
	type = list(string)
	default = ["us-west-2a", "us-west-2b", "us-west-2c"]
}

Access elements:

locals {
	first_az = var.availability_zones[0] # "us-west-2a"
	all_zones = join(", ", var.availability_zones)
}

Use in resources:

resource "aws_subnet" "public" {
	count = length(var.availability_zones)
	availability_zone = var.availability_zones[count.index]
	# ... other config
}

Maps

Key-value pairs:

variable "instance_types" {
	type = map(string)
	default = {
		dev = "t2.micro"
		prod = "t2.large"
	}
}

Access values:

resource "aws_instance" "app" {
instance_type = var.instance_types["prod"]
# Or with lookup function
instance_type = lookup(var.instance_types, var.environment, "t2.micro")
}

Objects

Structured data with different types:

variable "database_config" {
	type = object({
	instance_class = string
	allocated_storage = number
	multi_az = bool
	backup_retention = number
	})
	default = {
	instance_class = "db.t3.micro"
	allocated_storage = 20
	multi_az = false
	backup_retention = 7
	}
}

Use in resources:

resource "aws_db_instance" "main" {
	instance_class = var.database_config.instance_class
	allocated_storage = var.database_config.allocated_storage
	multi_az = var.database_config.multi_az
	backup_retention_period = var.database_config.backup_retention
}

List of Objects

The power combo - multiple structured items:

variable "servers" {
	type = map(object({
		size = string
		disk = number
	}))
	default = {
		web-1 = { size = "t2.micro", disk = 20 }
		web-2 = { size = "t2.small", disk = 30 }
	}
}
resource "aws_instance" "servers" {
	for_each = var.servers
	instance_type = each.value.size

	tags = {
		Name = each.key
	}
	root_block_device {
		volume_size = each.value.disk
	}
}

Sets and Tuples

Set - Like list but unordered and unique:

variable "allowed_ips" {
	type = set(string)
	default = ["10.0.0.1", "10.0.0.2"]
}

Tuple - Fixed-length list with specific types:

variable "server_config" {
	type = tuple([string, number, bool])
	default = ["t2.micro", 20, true]
}

Rarely used. Stick with lists and maps for most cases.

Variable Validation

Add rules to validate input:

variable "environment" {
	type = string
	description = "Environment name"

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

variable "instance_count" {
	type = number
	default = 1

	validation {
		condition = var.instance_count >= 1 && var.instance_count <= 10
		error_message = "Instance count must be between 1 and 10."
	}
}

Catches errors before Terraform runs.

Validation Check Terraform
Validation Check

Sensitive Variables

Mark secrets as sensitive:

variable "db_password" {
	type = string
	sensitive = true
}

Won’t appear in logs or plan output. Still stored in state though (encrypt your state!).

Variable Precedence

Multiple ways to set variables. Terraform picks in this order (highest to lowest):

  1. Command line: -var="key=value"
  2. *.auto.tfvars files (alphabetical order)
  3. terraform.tfvars file
  4. Environment variables: TF_VAR_name
  5. Default value in variable block

Setting Variables with Files

Create terraform.tfvars:

environment = "prod"
instance_type = "t2.large"
database_config = {
instance_class = "db.t3.large"
allocated_storage = 100
multi_az = true
backup_retention = 30
}

Run terraform apply - picks up values automatically

Or environment-specific files:

# dev.tfvars
environment = "dev"
instance_type = "t2.micro"
terraform apply -var-file="dev.tfvars"

Locals: Computed Values

Variables are inputs. Locals are calculated values you use internally.

variable "project_name" {
	type = string
	default = "myapp"
}

variable "environment" {
	type = string
	default = "dev"
}

locals {
	resource_prefix = "${var.project_name}-${var.environment}"

	common_tags = {
		Project = var.project_name
		Environment = var.environment
		ManagedBy = "Terraform"
	}

	is_production = var.environment == "prod"
	backup_count = local.is_production ? 3 : 1
}
resource "aws_s3_bucket" "data" {
	bucket = "${local.resource_prefix}-data"
	tags = local.common_tags
}

Use var. for variables, local. for locals.

Outputs

Display values after apply:

output "bucket_name" {
	description = "Name of the S3 bucket"
	value = aws_s3_bucket.data.id
}

output "is_production" {
	value = local.is_production
}

output "db_endpoint" {
	value = aws_db_instance.main.endpoint
	sensitive = true # Don't show in logs
}

View outputs:

terraform output
terraform output bucket_name

Real-World Example

variable "environment" {
	type = string
	validation {
		condition = contains(["dev", "staging", "prod"], var.environment)
		error_message = "Must be dev, staging, or prod."
	}
}

variable "app_config" {
	type = object({
	instance_type = string
	min_size = number
	})
}

locals {
	common_tags = {
		Environment = var.environment
		ManagedBy = "Terraform"
	}

	# Override for production
	min_size = var.environment == "prod" ? 3 : var.app_config.min_size
}

resource "aws_autoscaling_group" "app" {
	name = "myapp-${var.environment}-asg"
	min_size = local.min_size
	desired_capacity = local.min_size
	tags = [
		for key, value in local.common_tags : {
		key = key
		value = value
		propagate_at_launch = true
		}
	]
}

Quick Reference

Basic types:

variable "name" { type = string }
variable "count" { type = number }
variable "enabled" { type = bool }

Complex types:

variable "zones" { type = list(string) }
variable "types" { type = map(string) }
variable "config" { type = object({ name = string, size = number }) }
variable "servers" { type = map(object({ size = string, disk = number })) }

Validation:

validation {
condition = contains(["dev", "prod"], var.env)
error_message = "Must be dev or prod."
}

Locals and Outputs:

locals { name = "${var.project}-${var.env}" }
output "result" { value = aws_instance.app.id, sensitive = true }

Variables make your code flexible. Complex types model real infrastructure. Locals keep things DRY. Outputs share information.

With variables and locals in your toolkit, you now know how to make your Terraform code flexible and maintainable. But where does Terraform store the information about what it created? And how does it connect to AWS, Azure, or other cloud providers? That’s what we’ll explore next with state management and providers.

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...

Important Information

Terms of Use Privacy Policy Guidelines We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions β†’ Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.