Companion repository for the IAC from Zero Coursera course — course 21 of the Rust for Data Engineering specialization.
Twelve side-by-side demos that teach IAC fundamentals by pairing one OpenTofu
feature with its forjar equivalent. Every
demo ships both an HCL main.tf and a forjar.yaml, so the diff between the
two files IS the lesson.
- M1 — first apply — declarative IAC, plan/apply, BLAKE3 lock files
(cookbook recipe 01
developer-workstation) - M2 — state and plan — saved plans (recipe 30) and JSON plan output
(recipe 31):
tfplanfiles vs forjar lock files;terraform show -jsonvsforjar plan --format json - M3 — lifecycle and refactoring —
lifecycleblocks (recipe 33),movedblocks (recipe 34),-target(recipe 36) vs forjar's idempotent recipes and content-addressed resource IDs - M4 — drift and convergence —
refresh-only(recipe 35),checkblocks (recipe 32),terraform_remote_state(recipe 39) vs forjar's local BLAKE3 compare, runtime contracts, and pinned recipe imports - M5 — testing, security, capstone —
.tftest.hcl(recipe 37), state encryption (recipe 38), and a canary-deployment capstone (recipe 94) asserting all 10 falsifiable forjar claims against a real fleet
| Lesson | OpenTofu feature | forjar concept | Demo directory |
|---|---|---|---|
| 1.1.3 | terraform apply |
forjar apply + BLAKE3 lock |
m1-first-apply/ |
| 2.1.2 | terraform plan -out=plan.tfplan |
forjar plan --lock |
m2-state-and-plan/2.1.2-saved-plan/ |
| 2.1.3 | terraform show -json |
forjar plan --format json |
m2-state-and-plan/2.1.3-json-plan/ |
| 3.1.1 | lifecycle { prevent_destroy } |
idempotent recipe + content hash | m3-lifecycle/3.1.1-lifecycle/ |
| 3.1.2 | moved { from to } |
recipe composition by BLAKE3 ID | m3-lifecycle/3.1.2-moved-blocks/ |
| 3.1.3 | terraform apply -target= |
forjar apply --recipe |
m3-lifecycle/3.1.3-resource-targeting/ |
| 4.1.1 | terraform plan -refresh-only |
local BLAKE3 hash compare | m4-drift/4.1.1-refresh-only/ |
| 4.1.2 | check { assert {} } |
forjar runtime contracts (C1–C10) | m4-drift/4.1.2-check-blocks/ |
| 4.1.3 | terraform_remote_state |
recipe import + hash pin | m4-drift/4.1.3-cross-config/ |
| 5.1.1 | .tftest.hcl |
forjar plan-test |
m5-testing-security/5.1.1-testing-dsl/ |
| 5.1.2 | state_encryption {} |
content-addressed signed state | m5-testing-security/5.1.2-state-encryption/ |
| 5.1.3 | full canary fleet | recipe 94 + all 10 contracts asserted | m5-testing-security/5.1.3-capstone-canary-fleet/ |
The cookbook recipe numbers (01, 30–39, 94) refer to
paiml/forjar-cookbook — the
qualification suite that proves forjar against real infrastructure. Each demo
directory is a minimal restatement of one cookbook recipe paired with the
equivalent Terraform/OpenTofu HCL.
- Rust 1.75+ (
rustup default stable) — forcargo install forjar tofu1.7+ orterraform1.5+ — for the OpenTofu/HCL side of every demo- Docker — recipe 01 (M1) and recipe 94 (M5 capstone) use container transports
git clone https://github.com/paiml/iac-from-zero
cd iac-from-zero
# One-time: install forjar from crates.io
make install
# Run validate + plan on all 12 demos (no real infrastructure touched)
make demo-all
# Run a single demo by lesson id
make demo-1.1.3 # first apply
make demo-2.1.2 # saved plans
make demo-5.1.3 # capstone canary fleetmake demo-all is the forjar half of the gate — it runs forjar validate,
forjar plan, and forjar plan --json on every forjar.yaml. The OpenTofu
half lives in two separate targets so the two toolchains stay decoupled:
make tofu-validate # tofu init -backend=false + tofu validate per main.tf
make tofu-fmt # tofu fmt -check per main.tfNo real apply runs unless you opt in with make apply-<lesson-id> (forjar
side, requires Docker on PATH).
The labs/ tree is the learner-doing half of this repo. Five
exercises map 1:1 to the five course modules, each with a starter
forjar.yaml, a reference solution under solution/, and a committed
expected-*.json fixture the solution must reproduce. CI gates the lab
solutions against drift via:
make verify # scripts/verify-fixtures.sh — diff solutions vs expected-*.jsonSee labs/README.md for the lab map and per-lab structure.
| Top-level path | Role |
|---|---|
m1-…/ … m5-…/ |
Reading: 12 OpenTofu ⇄ forjar side-by-side demos |
labs/ |
Doing: 5 exercises with expected-*.json fixtures |
recipes/ |
Reference: one full data-engineering recipe (de-pipeline-host.yaml) |
capstone/ |
The M5 capstone scaffold |
includes/ |
Shared YAML fragments (policy defaults, notify hooks); symlinked into every demo dir |
scripts/ |
verify-fixtures.sh and other CI helpers |
assets/ |
Hero SVG + PNG |
Dual-licensed under MIT or Apache-2.0 — pick the one that fits your downstream
use. SPDX: MIT OR Apache-2.0.