Terraform Fundamentals & IaC
Terraform is HashiCorp's declarative infrastructure-as-code tool. You describe the desired end state in HCL and Terraform plans and executes the changes needed to reach it.
What is this?
Terraform is an open-source Infrastructure as Code (IaC) tool from HashiCorp that lets you define cloud and on-premise resources in declarative configuration files. You describe the desired end state, and Terraform Core builds a dependency graph, compares your config against the real world and the state file, and executes exactly the changes required. Providers are plugins that translate Terraform's generic resource types into the specific APIs of AWS, Azure, GCP, Kubernetes and hundreds more.
Why do you need it?
- Declarative: you write the target state and Terraform figures out the steps — no imperative scripts that drift.
- Idempotent: running apply repeatedly converges to the same result and only changes what differs.
- Drift detection: terraform plan constantly compares config, state and reality so manual changes are caught.
- Multi-cloud: one tool, one workflow, across AWS, Azure, GCP and any API with a provider.
- Versioned and reviewable: infrastructure lives in git, goes through pull requests, and can be rolled back.
Mental model
An architect's blueprint
A Terraform configuration
The blueprint describes the finished building, not the exact sequence of hammering. The construction crew figures out the steps. Terraform reads your blueprint (.tf files) and works out the concrete actions needed to match it.
How it works
- You write .tf files that declare the desired state of your infrastructure.
- terraform init reads the provider requirements, downloads the provider plugins and initializes the state backend.
- terraform plan refreshes current state, builds a resource dependency graph and computes an execution plan showing every create, update or destroy.
- terraform apply executes the plan against the provider APIs in dependency order.
- The resulting real-world resource IDs and attributes are recorded in terraform.tfstate, which drives every future plan.
The Terraform core-to-provider loop.
Key commands
terraform versionPrint the installed Terraform version.
terraform initInitialize the working directory: downloads providers and configures the backend.
terraform validateValidate the syntax and internal consistency of the configuration.
terraform fmtRewrite configuration files into canonical HCL formatting.
terraform planShow the execution plan: a dry run of what would change.
terraform applyCreate or update the resources declared in the configuration.
terraform destroyRemove every resource tracked in the state file.
terraform state listList all resource addresses currently tracked in state.
Examples
A first resource that needs no cloud account
terraform { required_providers { local = { source = "hashicorp/local" version = "~> 2.4" } }} resource "local_file" "greeting" { content = "Hello, Terraform!" filename = "${path.module}/hello.txt"}This is the smallest complete configuration. It declares the local provider and one resource that writes a file. Run terraform init, then terraform plan and terraform apply, and hello.txt appears on disk — with no cloud credentials required.
In production
- Infrastructure is stored in git and goes through pull-request review, replacing ad-hoc click-ops.
- One tool provisions consistent environments across AWS, Azure and GCP.
- Compliance: every change is a reviewable diff instead of a console click.
- CI/CD pipelines run terraform plan on every PR and apply only after approval.
Best practices
- Always review terraform plan output before applying.
- Keep configuration in version control; never commit state files or the .terraform directory.
- Pin provider versions with version constraints in required_providers.
- Keep configurations small, single-purpose and per-environment.
- Use remote state and locking as soon as more than one person touches the infrastructure.
Common mistakes
- Running terraform apply without reviewing the plan.
- Committing terraform.tfstate and .terraform to git.
- Fixing things in the console and never updating the config, causing drift.
- Hand-editing the state file instead of using terraform state commands.
Common issues
Error: Missing required argumentA required attribute of a resource was not set.
Read the provider documentation for the resource type and add the required argument.
Provider registry.terraform.io/hashicorp/aws: no suitable version installedThe provider was not initialized or the version constraint cannot be satisfied.
Run terraform init, or terraform init -upgrade to fetch a matching provider version.
Backend configuration changedThe backend block was edited after init, so Terraform refuses to guess.
Re-run terraform init -reconfigure to apply the new backend settings.
Debugging tips
- terraform validate quickly catches syntax and attribute errors before planning.
- Set TF_LOG=DEBUG terraform plan to see every provider API call and the reason for the failure.
- terraform providers lists the exact provider plugins and versions being used.
- Learn the plan symbols: + create, ~ update, - destroy, -/+ replace, and read them line by line.
Interview checkpoint
Hands-on lab
- Verify the Terraform CLI is installed
- Write a minimal HCL configuration
- Initialize, validate, plan and apply
- Inspect state and clean up with destroy
Your First Terraform Project
25 min · beginner
Quick quiz
Which command downloads and installs the provider plugins for a configuration?
Running terraform apply twice on an unchanged configuration creates duplicate resources.
Which file records the real-world IDs of the resources Terraform manages?
Cheat sheet
terraform initInstall providers, init backendterraform planPreview changes (safe dry-run)terraform applyExecute the planterraform destroyTear down everythingterraform validateCheck config syntaxterraform fmtFormat HCL canonicallyterraform state listShow managed resources