Terraform Fundamentals - Variables
Learn about Terraform variables, supported variable types and how to set variables via CLI, .tfvars file and environment variables.
We have already seen the usage of variable in few of the earlier posts, in this post let’s go through Terraform variables in detail. Variables are great if we want to reuse our code across different environments, projects, or cloud accounts where hardcoded values become a liability. They make the Terraform code modular, flexible, and scalable.
Terraform supports several variable types. The most common is the string
—used for simple text values like region names, instance types, or AMI IDs. Next is the number
type, useful for setting things like port numbers or counts. We also have list
types (a collection of items,) and map
types (key-value pairs).
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.
We can define default values for variables, making them optional, or we can leave them undefined to force explicit input at runtime. Terraform lets us set variable values in several ways: inline via the CLI using -var
, from a .tfvars
file, or even by reading environment variables using the TF_VAR_
prefix. For example, setting TF_VAR_region=us-east-1
in our shell will inject that value directly into any variable named region
.
Let’s put all this into practice.
We will create a variable-driven Terraform project that will provision a AWS Security Group. This project is also available in 100 Days of Red Team GitHub repository.
Create terraform-variable-sg
directory:
CMD:
mkdir terraform-variable-sg && cd terraform-variable-sg
PowerShell:
mkdir terraform-variable-sg; cd terraform-variable-sg
Create following files within this directory:
main.tf
provider "aws" {
region = var.region
}
# Fetch default VPC
data "aws_vpc" "default" {
default = true
}
resource "aws_security_group" "red_team_sg" {
name = var.sg_name
description = "Security group for red team infrastructure"
vpc_id = data.aws_vpc.default.id
dynamic "ingress" {
for_each = var.allowed_ingress_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
cidr_blocks = var.allowed_cidrs
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = var.tags
}
variables.tf
variable "region" {
description = "AWS region to deploy into"
type = string
}
variable "sg_name" {
description = "Name of the security group"
type = string
default = "red-team-sg"
}
variable "allowed_ingress_ports" {
description = "List of allowed inbound ports"
type = list(number)
}
variable "allowed_cidrs" {
description = "List of CIDR blocks allowed to access"
type = list(string)
}
variable "tags" {
description = "Tags to assign to the resource"
type = map(string)
default = {
Environment = "RedTeam"
ManagedBy = "100 Days of Red Team"
}
}
terraform.tfvars
region = "us-east-1"
allowed_ingress_ports = [22, 443]
allowed_cidrs = ["203.0.113.5/32", "198.51.100.10/32"]
tags = {
Operation = "Redirector Security Group"
Expiry = "2025-05-30"
CreatedBy = "100 Days of Red Team"
}
We can also provide variable values via CLI:
terraform apply \
-var='region=us-east-1' \
-var='allowed_ingress_ports=[22,443]' \
-var='allowed_cidrs=["203.0.113.5/32","198.51.100.10/32"]' \
-var='tags={Operation="Redirector Security Group", Expiry="2025-05-30", CreatedBy="100 Days of Red Team"}'
Note:
Use single quotes to wrap the entire
-var
argument.Use double quotes inside the map to define key-value pairs properly.
OR via environment variables:
export TF_VAR_region="us-east-1"
export TF_VAR_allowed_ingress_ports='[22,443]'
export TF_VAR_allowed_cidrs='["203.0.113.5/32","198.51.100.10/32"]'
export TF_VAR_tags='{Operation="Redirector Security Group", Expiry="2025-05-30", CreatedBy="100 Days of Red Team"}'
terraform apply
From within the terraform-variable-sg/
directory, run the lifecycle commands:
terraform init
terraform plan
terraform apply
This will create a security group allowing access to ports 22 and 443 from the two IP ranges we provided.
To destroy the resources after testing:
terrafrom destroy
This Terraform configuration creates an AWS Security Group using variable-driven input. It allows inbound TCP traffic on specified ports from a list of trusted IP addresses and permits all outbound traffic by default. The resource is also tagged dynamically based on engagement specific metadata.
TL;DR
- Terraform supports variables to make the code reusable.
- Supported variable types include string, number, list, map etc.
- Variables can be set via .tfvars files, CLI flags, and environment variables.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.