Day 153 Β· Blueprints for the building itself

Infrastructure as Code & Environments

You will be able to
  • Explain why infrastructure should be declared as versioned code, not clicked in a console
  • Build a mental model of Terraform: state, plan, and apply
  • Separate dev/staging/prod and manage config versus secrets across them
  • Write IaC-lite for the capstone's pieces and understand configuration drift
Today's ~120 minutes
Spaced-rep warm-up: cloud + CI/CD cards (D150/D152)10 min
ELI5 + tech read: IaC, state/plan/apply, environments, drift20 min
Guided: Terraform plan/apply loop + drift detection (Docker provider)40 min
Practice: environments + config/secret split design15 min
Project: IaC-lite for the capstone25 min
Quiz + flashcards10 min

Builds on: Day 150 β€” Cloud fundamentals Β· Day 151 β€” Deploy lab β€” container to cloud URL Β· Day 152 β€” CI/CD with GitHub Actions

The analogy

On Day 151 you built your deployment by hand β€” clicking through a console, setting variables, wiring things together. It worked. But could you rebuild it, identically, next month? In a second region for a customer? After someone accidentally deletes it? "Click-ops" leaves no record; the running system IS the documentation, and when it's gone, so is the knowledge.

Infrastructure as Code is the blueprint for the building itself. Instead of clicking, you *write down* what the infrastructure should be β€” "one container service, one managed vector store, these environment variables, this region" β€” in a file, and a tool reads that file and makes reality match it. Change the blueprint, re-apply, and the tool figures out the difference and adjusts. The blueprint lives in git, so infrastructure gets the same superpowers your code has: review, history, rollback, and reproducibility. And because it's declarative β€” you describe the destination, not the turn-by-turn directions β€” you can stamp out a dev, a staging, and a prod environment from the same blueprint with a few variables changed, confident they actually match. The building is no longer a thing you remember how to build; it's a thing you can regenerate from a file.

Why this matters on the job

"It works on my machine" scaled up to whole environments is "it works in staging but prod is subtly different" β€” the drift that causes the deploy that passed staging to fail in production. IaC kills that class of bug by making environments reproducible from one source. For an FDE, this is decisive: a customer wants your system in *their* cloud, their region, their account (Day 170), and handing them a reviewed Terraform config beats a runbook of console clicks that no one can audit or reproduce. It's also disaster recovery β€” if an environment is destroyed, you apply it back β€” and a security-review asset (Day 159), because the blueprint is exactly what auditors want to read. Interviewers ask how you'd manage multiple environments; "declared as code, promoted through the pipeline" is the senior answer.

Guided practice

guided 1

Read a plan, then apply β€” the Terraform loop (Docker provider)

22 min

You'll learn the plan/apply loop locally against the Docker provider β€” no cloud account or spend required β€” following HashiCorp's official getting-started tutorial.

  1. Install Terraform (or use a container image). Create learn-tf/main.tf from HashiCorp's Docker-provider quickstart: it declares a Docker image resource and a container resource (e.g. an nginx container on a port).
  2. terminal: terraform init β€” downloads the provider. Read what it created (.terraform/, a lock file).
  3. terminal: terraform plan β€” read the diff carefully: every resource marked + create. This is the "measure twice" step; nothing has happened yet.
  4. terminal: terraform apply β€” confirm, and watch it create the container. Verify with docker ps.
  5. Change the config (e.g. the published port), plan again, and read how Terraform shows an in-place update vs a destroy/recreate. apply it.
  6. terminal: terraform destroy β€” tear it all down from the blueprint, and confirm with docker ps. This is the reproducibility payoff: create and destroy from one file.
guided 2

Simulate and detect configuration drift

18 min
  1. With your Docker-provider container still applied (re-apply if you destroyed it), make a *manual* change outside Terraform: stop or rename the container by hand. terminal: docker stop <name> or change it via the Docker CLI.
  2. Run terminal: terraform plan again. Read how Terraform detects the divergence between its recorded state and reality β€” it proposes to recreate/fix the resource. This is drift detection in action.
  3. terminal: terraform apply to re-assert the declared state and heal the drift.
  4. Write iac/DRIFT.md: define configuration drift in your own words, describe the manual change you made, paste the plan diff that caught it, and state the team rule that prevents drift (all infra changes go through code + PR, never the console).
  5. Connect it back: this is the same discipline as the Day-141 gate β€” change the system only through the reviewed artifact, never by hand.

On your own

Design the capstone environments and config/secret split

15 min

Write iac/ENVIRONMENTS.md planning how the capstone's infrastructure is expressed as code across dev/staging/prod. Specify: (1) which properties are variables that differ per environment (image tag, replica count/size, region, log level) versus constants; (2) exactly which values are *config* (in the IaC, versioned) versus *secrets* (in a secret manager, referenced by name) β€” list each of the capstone's real settings on the correct side; (3) how staging is kept "prod-shaped" so a passing staging deploy is meaningful; (4) how the Day-152 pipeline promotes a build through the environments (auto to staging, approval to prod); (5) where Terraform state lives for a team and why it needs protection.

Hints: the classic mistake is putting a secret (an API key or DB password) into a variable that ends up in state or a committed tfvars file β€” every secret must be a reference to a secret store, never a literal in IaC.

Ship before you stop

IaC-lite for the capstone

Express your capstone's deployment as reviewable infrastructure code rather than console clicks. Deliver an iac/ directory with: Terraform (or your platform's IaC β€” e.g. a Compose file promoted to the source of truth, a Railway/Render config, or a real Terraform config if your platform has a provider) declaring the capstone's runtime β€” the container service, its persistent vector store, environment/config, and region β€” parameterized by an environment variable for staging vs prod. Include ENVIRONMENTS.md (the config/secret split and promotion plan) and DRIFT.md (drift defined, detected in the guided lab, and the no-manual-changes rule). Prove the loop: show a plan diff and a successful apply/destroy cycle (the Docker-provider lab counts as the working demonstration), and show that no secret value appears anywhere in the committed IaC or state.

Rubric β€” check what you completed (0/6)

Common mistakes & misconceptions

  • Managing infrastructure by clicking in the console. Click-ops is unreproducible and undocumented; declare it as code so it can be reviewed, versioned, and regenerated.
  • Putting secrets in Terraform variables or a committed tfvars file. They leak into state and git; reference a secret manager by name and keep values out of IaC entirely.
  • Running apply without reading the plan. plan is the measure-twice step; applying blind can destroy and recreate a stateful resource (like your vector store) and lose data.
  • Ignoring state, or keeping it only on one laptop. Terraform state is the source of truth it diffs against; a team needs a shared, protected remote backend or plans conflict.
  • Making a "quick manual fix" in the console. It causes configuration drift; the blueprint is now a lie, and the next apply may revert your fix or the fix may mask a real diff β€” change only through code.
  • Letting staging drift away from prod. If staging is a different shape, "passed staging" stops predicting prod behavior; keep them the same shape, differing only in size.
Knowledge check

Q1. What does `terraform plan` do, and why run it before apply?

Q2. Which value should NOT live in your versioned Terraform config?

Q3. Someone changes a setting directly in the cloud console. What is this called and how does Terraform surface it?

Go deeper β€” curated resources

docsTerraform β€” Introduction (what & why) β†—20 mincourseTerraform β€” Docker get-started tutorial β†—30 mincourseMade With ML β€” infrastructure & environments β†—20 min
If you have a third hour
  • Terraform remote state & workspaces β†— β€” Read how remote state backends and workspaces let a team share one source of truth and stamp out staging/prod from one config β€” the mechanics behind Day 154's promotion pipeline.
Done means
  • Terraform plan/apply/destroy loop run against the Docker provider
  • Drift simulated by a manual change and detected via plan; DRIFT.md written
  • Capstone infrastructure declared as code, parameterized by environment
  • Config/secret split correct β€” no secret literal in any committed IaC or state
  • Quiz β‰₯ 2/3
How this connects

← Back: This turns the Day-151 hand-built deployment into a reproducible blueprint on the Day-150 cloud tier, and applies Day 141's "change only through the reviewed artifact" rule to infrastructure itself.

Forward β†’: Day 154 promotes a build through these staging/prod environments in one pipeline; Day 159 hands the IaC to a security review; Day 161 relies on reproducible infra for the production cutover, and Day 170 ships this blueprint into a customer's own cloud account.

Unlocks: D154 Week 22 Checkpoint: Staging Pipeline Β· D159 Production Security & Compliance Basics