Infrastructure as Code with Terraform

Declarative Cloud Provisioning, State Locking & Reusable Modules

A video course on Terraform: 8 modules, 37 lessons, each lesson one video of five to ten minutes. The screen is a single session - an editor writing HCL on one side, a terminal running the real `terraform` CLI on the other - and the captions highlight the word being spoken.

Intermediate · 3 hours · 37 lessons · 191 labs

Related guides

Who it is for

Intermediate level.

For engineers who create cloud infrastructure and want to describe it in reviewed, repeatable files with Terraform instead of clicking through a console.

What you don't need yet:

What helps:

Before you start:

Take first:

Take next:

Learning paths:

Nobody needs to know everything before they start. Each course builds on the one before, so a learning path takes you there step by step.

Labs

191 labs, 98 of them graded: you write the code, it runs, and graded labs check the result. The outline lists each lesson's labs.

What is free

Start free: First module free with an account. Pro: Every course, lab, handbook, practice exam and certificate.

Course outline

Core Concepts And Context

  1. What Is Infrastructure As Code? (2 labs): You can explain what infrastructure as code is, say what a declarative tool does that a script does not, and name what Terraform is for and what it is not for.
  2. The Licence, OpenTofu And IBM (2 labs): You can explain what the business source licence changed in twenty twenty three, what OpenTofu is and where it came from, who owns Terraform now, and choose between the two tools for a given team with reasons.
  3. Installing Terraform And Meeting The CLI (7 labs): You can install Terraform, confirm the version you are running, and use the two commands that cost nothing and catch most mistakes: format and validate.
  4. Providers And The required_providers Block (7 labs): You can declare the providers a configuration needs, explain the difference between requiring a provider and configuring one, read a version constraint, and say what the dependency lock file is for.

Your First Resource

  1. Writing Your First Configuration In HCL (6 labs): You can read and write the four kinds of thing that appear in a Terraform file: blocks, arguments, expressions and comments, and you can refer to one resource from another.
  2. Initialising The Working Directory (5 labs): You can explain the four jobs the initialise command does, say what is in the hidden directory it creates, and know which flag to reach for when re-initialising is not enough.
  3. Predicting Changes, Then Applying Them (7 labs): You can read an execution plan line by line, name every change symbol, save a plan to a file and apply exactly that plan, and explain why a plan is a prediction rather than a promise.
  4. Tearing It Down With Destroy (6 labs): You can preview and run a destroy, explain why destroy is a first class part of the workflow rather than an accident, and name the three ways a team stops the wrong thing being destroyed.

Variables, Outputs And Expressions

  1. Parameterising With Input Variables (8 labs): You can declare typed input variables with defaults, descriptions and validation rules, supply values in all five ways, and say which way wins when two of them disagree.
  2. Return Values: Outputs And Locals (6 labs): You can declare outputs and read them from the command line in raw and JSON form, use locals to name an expression once, and explain why a sensitive output is still plain text in state.
  3. Functions And Expressions In HCL (4 labs): You can combine Terraform expressions with collection, string, numeric, and encoding functions to derive predictable resource arguments.
  4. Querying Existing Infrastructure With Data Sources (2 labs): You can use a data source to read existing information, distinguish refresh from creation, and feed the result into a local resource safely.

Building A Network Module

  1. Why Modules: Composition Versus Monoliths (3 labs): You can explain module boundaries and choose a useful interface for a reusable network component.
  2. Writing A Custom Network Module (3 labs): You can build a local only network module with variables, resources, and outputs that a caller can compose.
  3. Calling Your Module And Passing Variables (3 labs): You can call a child module, pass typed values, and consume its outputs from a root configuration.
  4. The Terraform Registry And Public Modules (3 labs): You can evaluate a public registry module by source address, documentation, inputs, outputs, and ownership risk.
  5. Versioning And Pinning Modules (3 labs): You can version a module interface, pin a dependency, and plan an upgrade without surprising callers.

Compute And Meta Arguments

  1. Scaling Resources With Count (6 labs): You can create several instances of one resource with count, address each one by its index or all of them with a splat, and predict what a plan does when an element is removed from the list that drives the count.
  2. Iterating Over Maps With For Each (6 labs): You can create instances with for_each from a map or a set of strings, address them by key, move existing count instances to keys with moved blocks instead of recreating them, and show that removing one key leaves every other instance alone.
  3. Explicit Dependencies With Depends On (6 labs): You can read the dependency graph Terraform builds from references, recognise a hidden dependency that no reference expresses, declare it with depends_on on a data source, a resource or a module, and explain why a reference is the better fix whenever one exists.
  4. Safe Changes With Lifecycle Rules (7 labs): You can protect, ignore, trigger and reorder replacements with a resource's lifecycle block, read each rule's effect in a plan, and add preconditions that fail a plan with your own message.
  5. Provisioners: Why They Are A Last Resort (4 labs): You can write a local-exec provisioner on terraform_data, predict when it runs and what a failure or a destroy-time provisioner does, and explain why the documentation tells you to reach for something else first.

State, Drift And Databases

  1. What State Really Is And Why It Is Needed (6 labs): You can list and inspect Terraform state, read the parts of the state file, explain how refresh uses it, and say why Terraform cannot map configuration to real objects without it.
  2. Simulating A Managed Database (5 labs): You can build the course's local twin of a managed database, explain how each part maps to the cloud version, and show exactly where its generated password ends up: hidden from every command, and in plain text in the state file.
  3. Detecting And Fixing Configuration Drift (5 labs): You can detect drift with a refresh-only plan and a detailed exit code, read what the provider reports, and resolve it on purpose: put reality back with an apply, or accept it into state with a refresh-only apply and change the configuration to match.
  4. Importing Existing Resources (7 labs): You can bring an existing object under management with an import block and generated configuration, tidy that draft until the plan shows nothing but the import, and use the terraform import command when you must, knowing what each one exposes.
  5. Forcing Replacement (5 labs): You can read why a plan replaces an object, force a one-off replacement with the replace flag instead of the deprecated taint command, and write a standing replacement rule with replace_triggered_by and terraform_data.

Remote State And Locking

  1. The Problem With Local State (4 labs): You can show what goes wrong when state lives in a file on one laptop (plain-text secrets, copies that diverge, lost state, locks no one else can see) and name what a team's state storage must provide instead.
  2. Configuring A Remote Backend (7 labs): You can write a backend block (including an S3 backend with encryption and use_lockfile), explain why it accepts only literal values, move existing state into it with terraform init -migrate-state, and keep per-environment settings out of the code with partial configuration.
  3. State Locking With Use Lockfile (6 labs): You can explain what a state lock protects, read a lock conflict and wait it out with -lock-timeout, configure S3-native locking with use_lockfile, and judge when force-unlock is safe.
  4. Workspaces For Multiple Environments (7 labs): You can create, list, select and delete CLI workspaces, use terraform.workspace in expressions, find where each workspace's state is stored, and decide when separate environment directories are the safer choice.
  5. Security: Secrets In State And Ephemeral Values (7 labs): You can show that a sensitive value is still stored in plain text in state, keep a secret out of state with ephemeral variables and resources, and explain how write-only arguments deliver a secret to a provider without persisting it.

CI CD Testing And Policy

  1. Running Terraform In CI (5 labs): You can build a pipeline that checks formatting, initialises and validates without prompts, saves a plan for a person to approve, applies exactly that plan, and gets its cloud credentials from short-lived OIDC tokens rather than stored keys.
  2. Native Testing With Tftest Files (5 labs): You can write .tftest.hcl files whose run blocks plan or apply a module and assert on the result, test that a validation rejects bad input with expect_failures, and read a failed assertion's diff.
  3. Provider Mocking For Tests (6 labs): You can replace a provider with mock_provider, make its generated values predictable with mock_resource defaults, pin one address with override_data or override_resource, and make an override available at plan time with override_during.
  4. Policy As Code With OPA (6 labs): You can export a saved plan as JSON with terraform show -json, read its resource_changes, write a Rego deny rule that checks them, and run opa eval as a pipeline gate that fails on any violation.
  5. Releasing The Real Cloud Artifact (4 labs): You can explain what releasing the cloud repository means and does not mean, run its free release checks (init -backend=false, validate, mocked tests), read its cost estimate, and pin a tagged module release with a git ref or a registry version constraint.

Certification courses