Terraform fundamentals
Core versus providers
The terraform binary is a single executable containing Terraform core: the HCL parser, graph builder, state manager and plan/apply engine. Everything that talks to an API lives in providers - plugins downloaded by terraform init into .terraform/providers (or a configured plugin cache directory). Providers are versioned separately from Terraform, so a configuration usually pins both:
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
Building blocks
- Resources - objects Terraform creates, updates and destroys.
- Data sources - read-only lookups evaluated during refresh/plan; they create nothing.
- Variables, locals, outputs - inputs, computed intermediates, exported values.
- Registry -
registry.terraform.iohosts public providers and modules; private registries mirror the same protocol.
Traps
required_providersusessource = "namespace/type"; putting a bare name or a wrong namespace causesinitfailures or the wrong provider being installed.~> 5.1allows 5.x but not 6.0;>= 5.0is not a pin and can silently jump majors.- Questions frequently swap
resourceanddata- if the object already exists and is only read, it is a data source. - Aliased providers (
provider "aws" { alias = "west" }) must be passed explicitly to child modules. - A provider upgrade requires
terraform init -upgrade;initalone keeps the lock file version.
Rule of thumb
Ask "who makes the API call?" If the answer is the Terraform binary itself rather than a provider, the statement is false.