Lesson 2 of 7 · 22m
HCL, Resources, and State: The Mental Model
Resources are declared objects; state is Terraform's memory of what exists — understand that pairing and everything else follows.
Terraform's model is deceptively simple: HCL files declare resources; a state file records what Terraform has created; plan diffs the declaration against state+reality; apply reconciles. The whole tool is those four ideas.
HCL: resources and references
resource "aws_security_group" "web" {
name = "web-sg"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web" {
ami = "ami-0abc123"
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.web.id] # the graph edge
}aws_instance.web referencing aws_security_group.web.id is the dependency graph — Terraform orders creation automatically. Attributes on resources become references elsewhere; output blocks publish them for the next layer.
State is the source of truth
terraform.tfstate records every resource Terraform manages — ID, attributes, dependencies. It's how plan knows "no changes" vs "recreate": state is Terraform's memory, and it must match reality. Two rules that keep it honest:
- Never edit state manually —
terraform statesubcommands exist for surgical fixes. - Never lose state — it's encrypted-at-rest worthy and remote-backed on any team setup.
Try it yourself
The dependency graph explains why order doesn't matter in HCL:
// Terraform builds this graph from references, then walks it
const graph = {
"aws_security_group.web": [],
"aws_instance.web": ["aws_security_group.web"], // depends on
};
// Creation order: SG first, then instance — declared order is irrelevant.
console.log(Object.keys(graph).sort());Field notes
terraform showreads state;terraform importadopts existing resources into it.- Data sources (
data "aws_ami") read reality without managing it — for referencing infra you don't own. - State leaks: it contains attribute values including sensitive ones — remote state with encryption + access control is not optional on real setups.