All posts
terraformiacdevops

Terraform: A Practical Guide for Full-Stack Developers

A practical guide to Terraform — infrastructure as code, state management, and the discipline that keeps infrastructure changes reviewable.

SR

Suhail Roushan

August 6, 2026

·
4 min read
·
0 views

Manually clicking through a cloud console to provision infrastructure works fine until you need to do it again for staging, again for a second region, and again after someone accidentally deletes the wrong resource — Terraform exists to make that process a reviewable file instead of institutional memory.

Terraform is an infrastructure-as-code tool that lets you define cloud resources — servers, databases, networking, DNS — in a declarative configuration language (HCL), then plan and apply changes to match that configuration. It works across virtually every major cloud provider through a consistent workflow, tracking real infrastructure state so it knows exactly what needs to change between your current setup and your desired one.

Why Terraform Matters (and When to Skip It)

Manual infrastructure changes through a console are unreproducible, unreviewable, and easy to get subtly wrong across environments. Terraform configuration is version-controlled like application code — changes go through the same review process, and terraform plan shows exactly what will change before anything actually happens, removing the guesswork from infrastructure changes.

Skip Terraform for very small setups fully managed by a PaaS that doesn't expose (or need) infrastructure-level configuration — if there's no cloud infrastructure to actually manage beyond what your platform already handles, there's nothing for Terraform to do.

Getting Started with Terraform

# main.tf
terraform {
  required_providers {
    aws = { source = "hashicorp/aws" }
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "uploads" {
  bucket = "my-app-uploads"
}

resource "aws_db_instance" "main" {
  engine         = "postgres"
  instance_class = "db.t3.micro"
  allocated_storage = 20
  username       = "app_user"
  password       = var.db_password
}
terraform init
terraform plan
terraform apply

Core Terraform Concepts Every Developer Should Know

State is Terraform's source of truth for what actually exists. The state file maps your configuration to real infrastructure resource IDs — losing or corrupting it means Terraform loses track of what it's managing, which is why remote state storage (S3 with locking, Terraform Cloud) is standard practice, not an edge case.

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-east-1"
    dynamodb_table = "terraform-locks"
  }
}

plan before apply is the core safety discipline. Reviewing exactly what Terraform intends to create, modify, or destroy before it happens is what makes infrastructure changes safe to make with confidence — skipping straight to apply on unreviewed changes is how accidental resource deletions happen.

Modules package reusable infrastructure patterns. Rather than duplicating the same VPC or database configuration across every project, a module defines it once and gets parameterized per use — the same DRY principle as functions in application code, applied to infrastructure.

module "database" {
  source        = "./modules/postgres"
  instance_size = "db.t3.medium"
  environment   = "production"
}

Variables and outputs make configurations reusable across environments without duplicating the entire file — the same module deployed with different variable values for staging versus production.

Common Terraform Mistakes and How to Fix Them

Mistake 1: local state files not shared or backed up. A state file living only on one developer's machine is a single point of failure and prevents team collaboration. Fix: use a remote backend (S3, Terraform Cloud) with locking from the start of any real project.

Mistake 2: running apply without reviewing plan output first. This is how unintended resource destruction happens, especially on shared infrastructure. Fix: always review plan output carefully, and require it as part of your change review process, not just a personal habit.

Mistake 3: hardcoding secrets directly in .tf files. This puts credentials in version control. Fix: use variables sourced from a secrets manager or environment variables, never committed literal values.

When Should You Use Terraform Instead of Provider-Specific Tools?

Use Terraform when you're managing infrastructure across multiple providers, want a consistent workflow regardless of cloud vendor, or need the review/planning discipline it enforces for a team. Use provider-specific tools (AWS CDK, Pulumi with a general-purpose language) when you prefer writing infrastructure in a full programming language rather than HCL, or your infrastructure is deeply tied to one provider's specific tooling ecosystem.

Terraform in Production

Store state remotely with locking enabled from day one — this single practice prevents the most common and most damaging Terraform mistakes (concurrent conflicting applies, lost state). Also structure configurations into modules and separate state per environment (staging, production) so a change to one environment can't accidentally affect another.

If your team is still provisioning cloud infrastructure by clicking through a console, that manual process is exactly the gap Terraform closes — start with your most frequently recreated or most critical piece of infrastructure first.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch