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.
- Install Terraform from the official HashiCorp route for your OS (package manager on macOS and Ubuntu, binary download on Windows).
- Write
main.tf— a short HashiCorp Configuration Language (HCL) file describing one resource. Practice locally first; no cloud account needed. - Run
terraform initto download the providers your file needs. - Run
terraform planand read every line of what Terraform proposes to create, change, or delete. - Run
terraform applyand typeyesonly after the plan matches what you intended. - Run
terraform destroywhen 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:
| Command | What it does | When you run it |
|---|---|---|
terraform init | Downloads the provider plugins your configuration needs and sets up the working directory | Once per project, and again whenever you add a new provider |
terraform validate | Checks that your configuration is syntactically valid and internally consistent | Before every plan — catches typos instantly |
terraform plan | Compares desired state to real state and shows exactly what will change | Before every apply — no exceptions |
terraform apply | Executes the plan and creates, modifies, or deletes real infrastructure | Only after you have read the plan |
terraform destroy | Plans and applies the removal of everything in the current state | When tearing down practice projects or retiring a stack |
terraform fmt | Rewrites your files to the standard HCL style | Before every commit |
terraform state list | Shows the resources Terraform is currently tracking | Whenever 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:
| Symbol | Meaning | What to do |
|---|---|---|
+ | Resource will be created | Expected on first apply; on later applies, ask why something new appeared |
~ | Resource will be updated in place | Check which attributes change — some updates are harmless, some reload services |
- | Resource will be destroyed | Stop. Read the address twice. Make sure the deletion is intentional. |
-/+ | Resource will be destroyed and recreated | Highest-risk line in the plan — recreating a database or IP can mean data loss or downtime |
<= | Attribute value will be read at apply time | Normal 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.tfstateby hand. Useterraform statesubcommands 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 -destroyfirst 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.