Instead of monolithic scripts, the infrastructure was modularized for reusability
and maintainability.
๐ Terraform Project Structure
terraform/
โโโ environments/
โ โโโ dev/
โ โโโ staging/
โ โโโ prod/
โ โโโ main.tf
โ โโโ variables.tf
โ โโโ terraform.tfvars
โโโ modules/
โ โโโ network/ # VNet, Subnets, NSGs
โ โโโ compute/ # VMs or App Service
โ โโโ storage/ # Managed Disks, Storage Accounts
โโโ backend.tf # Remote state config
โโโ versions.tf # Provider versions
Network Module
# modules/network/main.tf
resource "azurerm_virtual_network" "main" {
name = "${var.prefix}-vnet"
address_space = [var.vnet_address_space]
location = var.location
resource_group_name = var.resource_group_name
tags = var.tags
}
resource "azurerm_network_security_group" "web" {
name = "${var.prefix}-nsg-web"
location = var.location
resource_group_name = var.resource_group_name
security_rule {
name = "AllowHTTPS"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "DenyAllInbound"
priority = 4096
direction = "Inbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
Compute Module (IaaS)
# modules/compute/main.tf
resource "azurerm_linux_virtual_machine" "main" {
name = "${var.prefix}-vm"
resource_group_name = var.resource_group_name
location = var.location
size = var.vm_size
admin_username = var.admin_username
network_interface_ids = [
azurerm_network_interface.main.id,
]
admin_ssh_key {
username = var.admin_username
public_key = file(var.ssh_public_key_path)
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
disk_size_gb = 30
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts-gen2"
version = "latest"
}
identity {
type = "SystemAssigned"
}
custom_data = base64encode(file("${path.module}/cloud-init.yaml"))
tags = var.tags
}
๐ฅ๏ธ Terraform Workflow Commands
# Initialize Terraform with remote backend
terraform init \
-backend-config="resource_group_name=rg-terraform-state" \
-backend-config="storage_account_name=stterraformstate"
# Validate configuration
terraform validate
# Plan changes (preview)
terraform plan -out=tfplan -var-file=environments/prod/terraform.tfvars
# Apply infrastructure changes
terraform apply tfplan
# Show current state
terraform show