Terraform Basics for Developers Who Need to Manage Infrastructure

Terraform defines infrastructure in HCL files you can version-control and apply reproducibly. Here is how to start using it as an application developer.

Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

May 18, 2026
10 min read
Terraform Basics for Developers Who Need to Manage Infrastructure

Terraform is infrastructure as code: it lets you define servers, databases, DNS records, and certificates in text files that you commit to git, review in pull requests, and apply with a single command. As an application developer, you should know enough Terraform to manage your own infrastructure without depending entirely on a dedicated ops person.

What Problem Terraform Solves

One AI engineering post, weekly

LLM benchmarks, prompt techniques, and token-cost breakdowns — not another AI news roundup.

Without infrastructure as code, infrastructure is configured manually through cloud provider dashboards. This creates two problems: the configuration is invisible (nobody knows exactly what settings were chosen without logging into every dashboard) and it is not reproducible (recreating the same infrastructure for a new environment requires remembering every manual step).

Terraform solves both problems. Your infrastructure configuration is in HCL (HashiCorp Configuration Language) files. Those files are committed to git. To recreate your entire infrastructure in a new environment, you run terraform apply. To make a change, you edit a file, review the diff, and apply it.

Core Concepts

Providers: Terraform providers are plugins that know how to create resources in a particular service. There are providers for AWS, Google Cloud, Azure, Vercel, Cloudflare, GitHub, PlanetScale, Stripe, and hundreds more. Each provider is declared in your Terraform configuration and downloaded by terraform init.

terraform {
  required_providers {
    vercel = {
      source  = "vercel/vercel"
      version = "~> 1.0"
    }
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
}

Resources: resources are the things you create: a Vercel project, a Cloudflare DNS record, an Upstash Redis instance. Each resource has a type (from the provider) and a configuration block.

resource "vercel_project" "web" {
  name      = "my-app"
  framework = "nextjs"

  git_repository = {
    type = "github"
    repo = "myorg/my-app"
  }
}

Data sources: data sources read existing resources that Terraform did not create. Useful for referencing a zone ID in Cloudflare without hard-coding it.

data "cloudflare_zone" "main" {
  name = "example.com"
}

Variables: parameterize your configuration so the same code works for different environments (staging, production) with different values.

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

Outputs: expose values from your Terraform resources for use in other systems or by humans:

output "deployment_url" {
  value = vercel_project.web.url
}

Team workspace

Ship faster with chat, meetings, and projects in one place — Zlyqor.

Start free

The Workflow: init, plan, apply, destroy

terraform init: downloads the required providers and initializes the working directory. Run this once when setting up the project, and again when you add new providers.

terraform plan: Terraform reads your configuration, compares it to the current state of your infrastructure, and shows you what changes would be made. This is a dry run. No changes are made. Read the plan carefully before applying.

terraform apply: applies the changes shown in the plan. Terraform prompts you to confirm before making any changes. After you confirm, it creates, updates, or destroys resources to match your configuration.

terraform destroy: destroys all resources managed by your configuration. Use carefully.

State Management

Terraform tracks what it has created in a state file (terraform.tfstate). This file maps your HCL configuration to real-world resource IDs. Without it, Terraform does not know what exists.

Why local state is dangerous for teams: if two team members apply Terraform simultaneously from their local machines with different state files, they will create conflicting resources or destroy each other's changes. State must be shared.

Remote state: store state in a backend that supports locking. The most common options:

  • S3 + DynamoDB: store the state file in an S3 bucket, use DynamoDB for locking. The traditional AWS approach.
  • Terraform Cloud: HCP Terraform (formerly Terraform Cloud) provides remote state, locking, and a web UI for plan/apply history. Free tier includes 500 resource hours per month.
  • GitLab CI / GitHub Actions backend: some CI providers offer Terraform state backends natively.
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
  }
}

Real Use Case: Next.js App with Vercel + Cloudflare + Upstash

A practical example of what Terraform manages for a Next.js application:

# Vercel project
resource "vercel_project" "web" {
  name      = "my-nextjs-app"
  framework = "nextjs"
}

# Environment variables for the Vercel project
resource "vercel_project_environment_variable" "redis_url" {
  project_id = vercel_project.web.id
  key        = "UPSTASH_REDIS_REST_URL"
  value      = upstash_redis_database.cache.rest_url
  target     = ["production", "preview"]
}

# Upstash Redis database
resource "upstash_redis_database" "cache" {
  database_name = "my-app-cache"
  region        = "us-east-1"
  tls           = true
}

# Cloudflare DNS pointing to Vercel
resource "cloudflare_record" "web" {
  zone_id = data.cloudflare_zone.main.id
  name    = "app"
  value   = "cname.vercel-dns.com"
  type    = "CNAME"
  proxied = true
}

Running terraform apply creates all of this in one command. Running it again after changing the Redis region updates only the Redis database. Running terraform plan before any change shows exactly what will be modified.

When Terraform Is Overkill

Terraform adds overhead. For a single-developer project or a simple app with one deployment, managing everything through the Vercel and Cloudflare dashboards is faster and simpler. The complexity of Terraform becomes worthwhile when:

  • You have multiple environments (staging and production) that need identical configuration
  • Multiple team members need to make infrastructure changes safely
  • You need to recreate your infrastructure reproducibly (disaster recovery, new region)
  • Your infrastructure is complex enough that the dashboard-clicking approach loses track of what was changed and when

When Terraform Is Essential

For any team beyond two or three developers, Terraform (or an equivalent tool like Pulumi) is essential. Infrastructure changes become part of your normal code review process. You catch mistakes before they hit production. You have an audit log of every infrastructure change. And you can on-board new engineers to your infrastructure without giving them dashboard access to click through.

Keep Reading


Pristren builds AI-powered software for teams. Zlyqor is our all-in-one workspace - chat, projects, time tracking, AI meeting summaries, and invoicing - in one tool. Try it free.

#terraform#infrastructure#devops#iac#cloudflare#vercel

// discussion

Comments

0/4000
Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

Visionary technologist, software engineer, and machine learning specialist. Founder and CEO of Pristren, directing engineering teams that ship production-grade AI/ML pipelines, mission-critical full-stack applications, and developer tooling. Creator of Zlyqor, the unified team workspace platform. Author of 540+ technical guides and benchmark research reports on large language models, agentic workflows, Model Context Protocol (MCP), and modern web stacks.

PristrenZlyqor