TFLAB02-Variables: The Five Core Types

Variables: The Five Core Types

🔧 Terraform Core ⭐ Beginner variable string number bool list map type / default / description

Scenario

Your team has been hardcoding values directly into Terraform configs — region names, instance counts, feature flags — all baked right into main.tf. Every time someone needs to change a value, they edit the config and risk introducing typos.

You need to extract these hardcoded values into variables so the same configuration can be reused across environments just by changing input values. Your task is to declare variables of every core type and use them in a simple S3 bucket config.

Your Objectives
  • Declare a string variable for the AWS region (default: us-east-1).
  • Declare a string variable for the environment name (default: dev).
  • Declare a number variable for a retention period in days (default: 30).
  • Declare a bool variable to toggle versioning on the bucket (default: true).
  • Declare a list(string) variable for a list of team members.
  • Declare a map(string) variable for additional tags.
  • Use all six variables in a single aws_s3_bucket resource and its related configuration blocks.

Additional Context

Every variable block has three key attributes: type (what kind of value is expected), default (the value used if none is provided), and description (documentation for the variable). If you omit default, Terraform will prompt interactively or expect the value to come from a .tfvars file, -var flag, or environment variable.

The five primitive/collection types cover nearly all use cases: string for text, number for integers and floats, bool for true/false flags, list for ordered sequences, and map for key-value pairs.

variables.tf

# variables.tf

# STRING — a single text value
variable "aws_region" {
  description = "AWS region to deploy into."
  type        = string
  default     = "us-east-1"
}

variable "environment" {
  description = "Environment name (dev, staging, prod)."
  type        = string
  default     = "dev"
}

# NUMBER — integers or floats
variable "retention_days" {
  description = "Number of days to retain objects before expiration."
  type        = number
  default     = 30
}

# BOOL — true or false
variable "enable_versioning" {
  description = "Whether to enable versioning on the S3 bucket."
  type        = bool
  default     = true
}

# LIST(STRING) — an ordered collection of strings
variable "team_members" {
  description = "List of team members who own this bucket."
  type        = list(string)
  default     = ["alice", "bob", "charlie"]
}

# MAP(STRING) — a set of key-value pairs
variable "extra_tags" {
  description = "Additional tags to apply to all resources."
  type        = map(string)
  default = {
    Project   = "demo"
    CostCenter = "engineering"
  }
}

main.tf

# main.tf

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
}

provider "aws" {
  region = var.aws_region    # Using the string variable
}

# S3 bucket — name includes environment to avoid collisions
resource "aws_s3_bucket" "data" {
  bucket = "team-data-${var.environment}-${var.retention_days}d"

  # merge() combines the extra_tags map with inline tags
  tags = merge(var.extra_tags, {
    Name        = "team-data-bucket"
    Environment = var.environment
    ManagedBy   = "terraform"
    TeamMembers = join(", ", var.team_members)  # list → string
  })
}

# Versioning — controlled by the bool variable
resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.data.id

  versioning_configuration {
    # bool → string conversion: true becomes "Enabled", false becomes "Suspended"
    status = var.enable_versioning ? "Enabled" : "Suspended"
  }
}

outputs.tf

# outputs.tf
output "bucket_name"       { value = aws_s3_bucket.data.id }
output "versioning_status" { value = var.enable_versioning ? "Enabled" : "Suspended" }
output "team_count"        { value = length(var.team_members) }
output "all_tags"          { value = aws_s3_bucket.data.tags_all }

Workflow Commands

terraform init
terraform plan

# Apply with defaults
terraform apply

# Override variables from CLI
terraform apply -var="environment=prod" -var="enable_versioning=false"

# Override with a list
terraform apply -var='team_members=["dave", "eve"]'

terraform destroy
✓ Expected Output After Apply
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

bucket_name       = "team-data-dev-30d"
team_count        = 3
versioning_status = "Enabled"
all_tags          = tomap({
  "CostCenter"  = "engineering"
  "Environment" = "dev"
  "ManagedBy"   = "terraform"
  "Name"        = "team-data-bucket"
  "Project"     = "demo"
  "TeamMembers" = "alice, bob, charlie"
})