How to Use Terraform: The Beginner's Guide to Your First IaC Project (2026)

CodexFuse Team · 2026-10-30T14:06:01.144Z · 13 min read

How do I use Terraform for the first time?

You use Terraform for the first time in four steps: install the Terraform binary, write a small HCL file that describes what you want, run terraform init to download providers, then run terraform plan followed by terraform apply to create it. The full beginner loop is install → write → init → plan → apply → destroy, and the one rule that matters from day one is this: always read the plan before you apply.

  1. Install Terraform from the official HashiCorp route for your OS (package manager on macOS and Ubuntu, binary download on Windows).
  2. Write main.tf — a short HashiCorp Configuration Language (HCL) file describing one resource. Practice locally first; no cloud account needed.
  3. Run terraform init to download the providers your file needs.
  4. Run terraform plan and read every line of what Terraform proposes to create, change, or delete.
  5. Run terraform apply and type yes only after the plan matches what you intended.
  6. Run terraform destroy when you are done practicing, so nothing keeps costing you money.

This guide walks through that entire loop on a safe local example first, then shows how the same loop applies to a real cloud resource — plus the state-file discipline and credential habits that separate beginners from people who learn them the expensive way. If you want the configuration-management half of the picture (installing software inside servers), read our Ansible beginner guide next — Terraform provisions the server, Ansible configures it.

What is Terraform, and what is it not?

Terraform is an infrastructure-as-code (IaC) tool by HashiCorp: you describe the infrastructure you want in HCL files, and Terraform figures out what to create, modify, or delete to reach that desired state. That "desired state" phrasing is the whole idea — Terraform is declarative, meaning you write what you want ("a server with 2 vCPUs in this region"), not the step-by-step how of clicking through a cloud console.

What Terraform is not: it is not a configuration-management tool. It does not install software inside your servers or manage running processes. Creating the server is Terraform's job; installing your app on the server is the job of Ansible, a startup script, or a container runtime like the one in our Docker beginner guide. Mixing those two jobs up is the most common beginner mistake, and keeping them separate is exactly why Terraform and Ansible are usually taught as a pair.

The payoff for writing files instead of clicking consoles is threefold: your infrastructure becomes reproducible (the same files build the same thing every time), reviewable (changes go through plan like code goes through code review), and version-controlled (the files live in Git, with history). A disaster-recovery story quoted in a 2026 DEV Community tutorial puts it well: a rebuild that took two engineers three days by hand became a fifteen-minute terraform apply once the stack was coded.

How do I install Terraform on Windows, macOS, and Linux?

Install Terraform from HashiCorp's official channels — never from an unofficial script or a random download mirror. The routes below were verified on the official install page at developer.hashicorp.com on October 30, 2026.

macOS (Homebrew):

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

Ubuntu / Debian:

wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

Windows: download the .zip binary from releases.hashicorp.com, extract it, and add the folder to your PATH. Then verify on every OS with:

terraform -v

HashiCorp also publishes step-by-step Get Started tutorial tracks for AWS, Azure, Google Cloud, Docker, Oracle Cloud, and HCP Terraform if you prefer a guided first project after this article.

What does my first HCL file look like?

Your first HCL file is a main.tf with one resource block — and the smart move is to practice on a local resource before touching a cloud account. The local_file provider writes a text file on your own machine, which teaches you the full write → init → plan → apply loop with zero billing risk.

# main.tf — your first Terraform configuration
terraform {
  required_version = ">= 1.0"
}

resource "local_file" "hello" {
  content  = "Hello, Terraform World!"
  filename = "hello.txt"
}

Three things to notice in that tiny file: resource declares what to create (a local file), its arguments declare the desired state (this exact content, at this exact path), and local_file.hello is the resource's address — provider type plus the name you chose. Every real resource you'll ever write (an EC2 instance, a DNS record, a database) follows this exact shape; only the provider and arguments change. The Terraform ecosystem now spans more than 3,000 providers, per a 2026 DEV Community guide, but the file shape is always the same.

What do terraform init, plan, apply, and destroy actually do?

These four commands are the Terraform lifecycle: init sets up the working directory, plan previews changes, apply executes them, and destroy removes everything Terraform created. Two more commands join your daily habit — validate checks syntax before you plan, and fmt keeps your files in the canonical style:

CommandWhat it doesWhen you run it
terraform initDownloads the provider plugins your configuration needs and sets up the working directoryOnce per project, and again whenever you add a new provider
terraform validateChecks that your configuration is syntactically valid and internally consistentBefore every plan — catches typos instantly
terraform planCompares desired state to real state and shows exactly what will changeBefore every apply — no exceptions
terraform applyExecutes the plan and creates, modifies, or deletes real infrastructureOnly after you have read the plan
terraform destroyPlans and applies the removal of everything in the current stateWhen tearing down practice projects or retiring a stack
terraform fmtRewrites your files to the standard HCL styleBefore every commit
terraform state listShows the resources Terraform is currently trackingWhenever you wonder "what does Terraform think it owns?"

Run the local example end to end now: mkdir terraform-beginner && cd terraform-beginner, save the main.tf above, then terraform init, terraform plan, terraform apply (type yes), and watch hello.txt appear. Finish with terraform destroy and watch it disappear. You have just run the same lifecycle that manages thousands of cloud resources in production.

Why is reading the plan before applying mandatory?

Reading the plan before applying is mandatory because the plan is the last moment anything is still free and reversible — after apply, the changes are real, billable, and sometimes destructive. Treat the plan like a code review for infrastructure: if a line surprises you, stop and investigate before typing yes.

Terraform marks every proposed change with a symbol. Learn to read them at a glance:

SymbolMeaningWhat to do
+Resource will be createdExpected on first apply; on later applies, ask why something new appeared
~Resource will be updated in placeCheck which attributes change — some updates are harmless, some reload services
-Resource will be destroyedStop. Read the address twice. Make sure the deletion is intentional.
-/+Resource will be destroyed and recreatedHighest-risk line in the plan — recreating a database or IP can mean data loss or downtime
<=Attribute value will be read at apply timeNormal for outputs and computed values; nothing to approve

Two habits make plan-reading reliable: run terraform plan -out=tfplan and then terraform apply tfplan so you apply exactly the plan you reviewed (not a fresh plan computed later), and never skip the plan on a Friday afternoon change you could make Monday morning.

What is Terraform state, and why can't I delete the state file?

Terraform state — the terraform.tfstate file — is Terraform's memory: it maps your HCL configuration to the real resources it created, and without it Terraform cannot know what already exists. Delete the state file and Terraform forgets everything it built; the next apply will try to create duplicates of resources that are already running, while destroy will report there is nothing to tear down — leaving orphaned, billable infrastructure behind.

The state rules for beginners are short and absolute:

  • Never edit terraform.tfstate by hand. Use terraform state subcommands for the rare cases you need to move or remove tracked resources.
  • Never delete the state file unless you are abandoning the infrastructure on purpose — and even then, destroy first.
  • Never commit raw state to Git unencrypted. State files can contain secrets (database passwords, keys) in plain text.
  • For anything beyond solo practice, use a remote backend (S3 with locking, Terraform Cloud / HCP Terraform, or your provider's equivalent) so state is shared, locked, and backed up — HashiCorp's own install page points to an HCP Terraform track for exactly this.

If you provision a real server with Terraform, our what-is-VPS-hosting guide is the natural companion read: it explains what the machine you just provisioned actually is, and when it is time to move up from shared hosting to it.

How do I connect Terraform to a cloud provider safely?

You connect Terraform to a provider with a provider block plus credentials delivered through environment variables or credential files — never pasted into .tf files and never committed to Git. Here is the AWS pattern (the same idea works for every provider):

# main.tf — AWS provider (credentials come from the environment, not this file)
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

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

resource "aws_s3_bucket" "demo" {
  bucket = "my-terraform-demo-bucket-2026"
}

Export credentials in your shell, or use the AWS CLI's aws configure to store them in ~/.aws/credentials:

export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
export AWS_DEFAULT_REGION="us-east-1"

Then the familiar loop takes over: terraform init downloads the AWS provider, terraform plan shows the bucket it will create, terraform apply creates it, and terraform destroy tears it down when you are done learning. Notice what the provider block does: it pins the provider source and version so the same configuration behaves identically on your machine and your teammate's.

How do variables, outputs, and modules keep Terraform code reusable?

Variables make configuration reusable across environments, outputs expose useful values after apply, and modules package resources into shareable building blocks. Hardcoding a bucket name works once; a variable works everywhere:

# variables.tf
variable "bucket_name" {
  description = "Name of the demo bucket"
  type        = string
}

# main.tf
resource "aws_s3_bucket" "demo" {
  bucket = var.bucket_name
}

output "bucket_arn" {
  description = "ARN of the created bucket"
  value       = aws_s3_bucket.demo.arn
}

Set the variable without editing files: terraform apply -var="bucket_name=my-demo-2026". Outputs print after apply and can be consumed by other configurations — the classic example is an output exposing a server's IP address that a second project needs.

A module is just a folder of .tf files with a clear input/output contract, called from a parent configuration:

module "web_bucket" {
  source      = "./modules/static-bucket"
  bucket_name = "my-demo-2026"
}

Start with one flat main.tf, split into variables.tf / outputs.tf / main.tf when it gets long, and reach for modules only when you find yourself copying the same resource blocks between projects. Beginners who modularize on day one usually build abstraction they don't yet understand — the flat file is the honest starting point.

What is the destroy discipline beginners miss?

The destroy discipline beginners miss is simple: every apply creates a billing obligation, and terraform destroy is how you close it — practice projects left running are the most common way beginners get surprise cloud bills.

Make destroy part of the loop, not an afterthought:

  • Destroy practice projects the same session you create them. S3 buckets cost pennies; a forgotten EC2 instance or load balancer does not.
  • Run terraform plan -destroy first when you are unsure — it previews the teardown the same way plan previews a build.
  • Know what destroy cannot remove. Anything created outside Terraform (manual console clicks, resources imported never) is invisible to state and will keep billing you. That is exactly the click-ops chaos IaC is meant to end.
  • Protect production with lifecycle { prevent_destroy = true } on resources like databases once you move past practice — Terraform will then refuse to destroy them until you remove the guard deliberately.

Terraform vs Ansible: which do I learn first?

Learn Terraform first if your problem is creating infrastructure (servers, networks, DNS, buckets); learn Ansible first if your problem is configuring servers that already exist (installing packages, writing config files, restarting services). Most real setups need both, in this order: Terraform provisions the machine, Ansible configures it. Our Ansible beginner guide picks up exactly where this one ends — the same install → first file → run → clean up arc, but for configuration management.

The one-line distinction the DEV Community beginner field draws: Terraform builds the house; Ansible furnishes it. A VPS you provision with Terraform and want to understand properly is covered in our VPS hosting explainer.

Sources

  • HashiCorp — "Install Terraform" (developer.hashicorp.com/terraform/install), install routes verified October 30, 2026 (Homebrew tap, Ubuntu/Debian APT repository, Windows binary; Get Started tutorial tracks for AWS, Azure, GCP, Docker, OCI, HCP Terraform).
  • Citadel CloudManagement — "Terraform for Beginners: Your First Infrastructure as Code Project" (dev.to, ~125 days old): write/plan/apply workflow, declarative definition, Terraform-vs-Ansible boundary, 3,000+ provider ecosystem in 2026, state rules (never hand-edit; remote S3 backend with locking for production).
  • HugoW — "Terraform Basics: Infrastructure as Code for Beginners — Complete Guide" (blog.hugow.dev): IaC definition, null_resource local practice pattern, terraform-block anatomy.
  • Linux Handbook — "Getting Started with Terraform: Your First Steps" (linuxhandbook.com, Terraform course chapter): local_file first-project walkthrough, init/plan/apply/destroy command semantics, validate/fmt daily commands.
  • Holori — "Getting Started with Terraform: A Step-by-Step Terraform Tutorial" (holori.com): AWS credential setup via environment variables, EC2 main.tf walkthrough, plan-review habit.

Frequently asked questions

Is Terraform free to use?

Yes — the Terraform CLI is free and open source. You pay only for whatever cloud resources your configurations create, which is why the destroy discipline in this guide matters: Terraform itself costs nothing, but a forgotten EC2 instance bills you all month.

Do I need a cloud account to learn Terraform?

No. Start with the local_file or null_resource examples in this guide — they teach the full init → plan → apply → destroy loop on your own machine. Open a cloud account only when you are ready for the provider section, and destroy the practice resources the same day.

Is Terraform declarative or imperative?

Terraform is declarative: you describe the desired end state in HCL and Terraform computes the steps to reach it. You never write "first do X, then do Y" — you write "I want this to exist," and the plan shows you the steps Terraform derived.

What happens if I delete terraform.tfstate?

Terraform loses its memory of what it created. The next apply will attempt to recreate resources that already exist (causing errors or duplicates), and destroy will find nothing to tear down — leaving orphaned, billable infrastructure. Restore from backup, or use terraform import to re-attach state to real resources.

Terraform vs OpenTofu — which should a beginner pick in 2026?

Terraform is the original HashiCorp tool; OpenTofu is the Linux Foundation's open-source fork with the same HCL syntax and a drop-in tofu binary. Everything in this guide — the workflow, the state rules, the plan-before-apply habit — applies to both. Learn the concepts here first; the fork question only matters once you are choosing tooling for a team.

Featured on Twelve Tools Launch Llama Tools Launch your MCP