Project challenges / verified progress
Beacon: build the ground it stands on

The engineering notebook

Plan before apply

How does Terraform turn HCL files into a safe proposed change?

Loading statusStage 2 of 9

  • Workspace not ready
  • Agent not ready
Focus25:00
A small focus ritual

0 focus sessions completed. Every fourth session offers a longer break. Start each phase when you are ready.

Study time never unlocks verified lesson progress.

Loading...

Loading verified progress...

Loading GitHub account...
Phase 1 — Terraform without a bill

Step 01 of 06

Learn the concept

Terraform's most important command is not apply. It is plan, because it lets a human read the blast radius before an API call spends money or deletes a thing. The symbols are small, and one of them, -/+, deserves your full attention every time.

WRITE, CHECK, PLAN, APPLY01Write HCLresources and references02fmt validatestyle and schema checks03Plangraph plus proposed diffread it04Applyprovider API callsspends money
Terraform builds a graph before it talks to providers. References such as `random_pet.name.id` are not string tricks; they are dependency edges that tell Terraform what must exist before another resource can be planned.
Step 01

The ideas this is made of

HCL is configuration with expressions

HashiCorp Configuration Language looks like nested blocks because infrastructure is full of named objects with arguments. It is not JSON with nicer comments. Expressions can reference variables, resources and functions. That is enough to build a graph. The graph is the point: Terraform can see that a file using a generated name depends on the resource that generated it.

Providers speak the provider protocol

Terraform Core does not know how to create a TLS key, an AWS subnet or a local file. Providers are separate plugins that expose schemas and implement create, read, update and delete operations through the provider protocol. That split is why the same workflow can manage a text file locally and a VPC remotely, while each provider still owns its API details.

References are dependency edges

When one resource argument refers to another resource's attribute, Terraform records an implicit dependency. You usually do not write depends_on; you write the real relationship. If a local file uses random_pet.suffix.id in its content, Terraform knows the random value must exist first. Explicit dependencies are reserved for rare relationships Terraform cannot infer from data flow.

The plan symbols are a risk language

+ means create. ~ means update without replacing the object. - means destroy. -/+ means replace, usually because an argument is marked ForceNew by the provider schema. Replacement is the one to slow down for: a new database may be fine, a replaced static IP may be a customer outage, and a replaced cluster may be a long afternoon.

Three local providers, no cloud bill
terraform {
  required_version = ">= 1.7.0"

  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.5"
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.6"
    }
    tls = {
      source  = "hashicorp/tls"
      version = "~> 4.0"
    }
  }
}

resource "random_pet" "suffix" {
  length = 2
}

resource "tls_private_key" "demo" {
  algorithm = "ED25519"
}

resource "local_file" "note" {
  filename = "generated/beacon-${random_pet.suffix.id}.txt"
  content  = tls_private_key.demo.public_key_openssh
}

This teaches providers, resources, references and a graph without any account. The generated file depends on both the random name and the public key because its arguments reference both resources.

How to read plan symbols

SymbolMeaningHuman question

+

Create

Is this expected and affordable?

~

Update in place

Will the live object restart?

-

Destroy

Who still depends on it?

-/+

Replace

What is lost during the gap?

What these are called on the job

  • Provider — A Terraform plugin that knows the schema and API operations for one platform or service.

  • Resource — A managed object Terraform can create, read, update and destroy.

  • Plan — Terraform's proposed set of actions after comparing configuration, state and provider reads.

  • ForceNew — A provider schema mark meaning a changed argument requires replacement instead of in-place update.