35-Day DevOps Bootcamp  ·  Day 21
Infrastructure as Code  ·  Terraform
Day 21: IaC Concepts
& Terraform Intro
⏱ 60 min 📚 Theory + Lab 🔨 Hands-on Terraform
Topics Covered
● Why Infrastructure as Code?
● Terraform Architecture
● HCL Basics
● First Terraform Configuration
● Lab: GitHub Provider
PrerequisitesGit, CLI basics
ToolsTerraform v1.x, GitHub account
Session Agenda
60-Minute Breakdown
Theory → Lab
0 – 15 min
📚 Why IaC?
Problems with manual infra  ·  IaC principles  ·  Key benefits
15 – 30 min
🏗 Terraform Architecture
Providers, resources, state, plan & apply lifecycle
30 – 40 min
💻 HCL Basics
Blocks, type system, references & interpolation
40 – 55 min
🔨 Lab: First Terraform Config
Install Terraform → GitHub provider → init / plan / apply
Part 1  ·  Why Infrastructure as Code?
The Problem with Manual Infra
Before IaC: click-ops, drift, and 2am disasters
🖱
Click-Ops in Console
Manual steps in web UIs — tedious, error-prone, and impossible to audit or reproduce reliably.
Snowflake Servers
Every server slightly different. "It works on mine" — the classic DevOps nightmare that kills deployments.
😵
"It Works in Staging"
Dev, staging, and prod environments drift apart over time. Surprise failures happen at the worst moments.
🔥
Disaster Recovery Hell
When a server dies, you're rebuilding from memory and stale screenshots. 6 hours for what should take 5 minutes.
💬
Real War Story
"Our staging server had 47 manual tweaks applied over 18 months. Nobody documented them. When production went down at 3am on Black Friday, it took 6 hours to rebuild." — Anon SRE
Part 1  ·  Why Infrastructure as Code?
IaC: Infrastructure as Software
IaC treats infrastructure configuration as software — version-controlled, testable, and repeatable.
📋
Consistency
Same config runs identically in dev, staging, and production every single time.
Speed
Spin up entire environments in minutes, not hours or days of manual work.
📚
Documentation
Your code IS your documentation — always current, always accurate.
🤝
Collaboration
Pull requests for infrastructure changes — with code reviews and approvals.
🔄
Disaster Recovery
Rebuild any environment from scratch in minutes, not days.
🔍
Audit Trail
Git history shows exactly who changed what infrastructure and when.
Part 2  ·  Terraform Architecture
5 Core Concepts
The complete mental model for Terraform
🔗 Provider
Plugin that lets Terraform talk to an API
e.g. azurerm, aws, github, datadog, kubernetes
📦 Resource
An infrastructure object to create or manage
e.g. VM, DNS record, S3 bucket, GitHub repository
💾 State (.tfstate)
Terraform's memory of what it's currently managing
Maps real-world resources to your config — NEVER commit to Git!
🗺 Plan
A preview of what WILL change before anything happens
terraform plan → shows +/- changes as a diff
🚀 Apply
Makes the actual changes to your infrastructure
terraform apply → creates, updates, or destroys resources
Part 2  ·  Terraform Architecture
The Terraform Workflow
1
terraform init
Downloads providers & sets up backend
2
terraform plan
Previews changes before applying anything
3
terraform apply
Creates / updates real resources
4
terraform destroy
Removes all managed resources cleanly
⚠ State File Warning — Critical Security Issue
The .tfstate file contains SENSITIVE DATA — passwords, private keys, IP addresses. NEVER commit it to Git. Use remote state in production: Azure Blob Storage, AWS S3 + DynamoDB, or Terraform Cloud.
Part 3  ·  HCL Basics
HashiCorp Configuration Language
Terraform's config language — structured, readable, just enough dynamism
Block Types
resource data variable output locals provider module terraform
Type System
string"hello world"
number42
booltrue / false
list["a", "b", "c"]
map{ key = "val" }
# References: resource_type.resource_name.attribute
resource "azurerm_resource_group" "main" {
  name     = "${var.prefix}-rg"    # String interpolation
  location = var.location        # Variable reference
  tags     = local.common_tags   # Local reference
}
Part 4  ·  Lab
First Terraform Configuration
Objective: Install Terraform and provision a real GitHub repository using code
1
Install Terraform
Use the command for your OS/package manager, then verify with terraform -version.
macOS (Homebrew): brew install terraform Windows (Winget): winget install Hashicorp.Terraform Windows (Chocolatey): choco install terraform Linux (APT): sudo apt-get update && sudo apt-get install -y terraform
2
Configure the GitHub Provider
Create main.tf with the required_providers block pointing to integrations/github
terraform { required_providers { github = { source = "integrations/github" version = "~> 6.0" } } }
3
Run terraform init
Initializes the working directory and downloads the GitHub provider plugin (~5 MB)
$ terraform init
4
Run terraform plan
Previews what Terraform WILL create — no changes made yet. Always review before applying!
$ terraform plan
5
Run terraform apply
Creates the actual GitHub repository in your account. Type yes to confirm.
$ terraform apply
📋 Prerequisites: GitHub account, Personal Access Token (repo scope), Terraform v1.x installed
Lab  ·  main.tf Walkthrough
main.tf — Managing a GitHub Repo with Terraform
# main.tf
terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 6.0"
    }
  }
}

provider "github" {
  token = var.github_token
}

variable "github_token" {
  description = "GitHub PAT"
  type       = string
  sensitive   = true
}

resource "github_repository" "devops_labs" {
  name        = "devops-35days-labs"
  description = "Labs for the 35-day DevOps course"
  visibility  = "public"
  auto_init   = true
  topics = ["devops", "terraform"]
}

output "repo_url" {
  value = github_repository.devops_labs.html_url
}
terraform block
Declares required provider version constraints. Pins the version to avoid breaking changes.
provider block
Configures GitHub auth. Token comes from an env variable via TF_VAR_github_token.
variable block
sensitive = true hides the token value from plan/apply output and logs.
resource block
Declares the actual GitHub repository to create. 1:1 mapping with a real resource.
output block
Prints the repo URL after successful apply. Reference uses dot notation.
Lab  ·  Running the Commands
From Code to Real Infrastructure
Step 1 — Set the token
macOS/Linux: export TF_VAR_github_token="ghp_yourPersonalAccessToken"
Windows PowerShell: $env:TF_VAR_github_token="ghp_yourPersonalAccessToken"
Windows CMD: set TF_VAR_github_token=ghp_yourPersonalAccessToken
→ TF_VAR_ prefix tells Terraform to use this as a variable. Never hardcode tokens in .tf files!
Step 2 — Initialize the workspace
$terraform init
→ Downloads the GitHub provider plugin. Creates .terraform/ directory. Run once per project.
Step 3 — Preview changes
$terraform plan
→ Shows exactly what will be created. Review carefully before applying — no changes happen yet.
Step 4 — Create the resource
$terraform apply
→ Type 'yes' to confirm. Creates the GitHub repo and prints the output URL.
Step 5 — Clean up (optional)
$terraform destroy
→ Removes all Terraform-managed resources. Use with caution in production!
Lab  ·  Expected Output
What Success Looks Like
terraform plan output
Terraform will perform the following actions:

  # github_repository.devops_labs
  + resource "github_repository" "devops_labs" {
    + name       = "devops-35days-labs"
    + visibility = "public"
  }

Plan: 1 to add, 0 to change, 0 to destroy.
terraform apply output
github_repository.devops_labs: Creating...
github_repository.devops_labs: Creation complete!

Apply complete! Resources: 1 added

Outputs:

repo_url = "https://github.com/you/devops-35days-labs"
Key things to notice
● Plan shows a diff before anything changes — always review it carefully
+ (green) = adding    ~ (yellow) = modifying    - (red) = destroying
● The output value (repo_url) is printed after successful apply
Day 21  ·  Recap
What You Learned Today
IaC treats infra as software — version-controlled, testable, repeatable
Terraform's 5 core concepts: Provider, Resource, State, Plan, Apply
HCL syntax: blocks, type system, references, and interpolation
Real Terraform config to manage a GitHub repository from code
The init → plan → apply → destroy workflow
State file security: remote state, never commit to Git
📋 Homework: Add a second resource (github_branch_protection) to your main.tf and apply it
🚀 Coming Up
Day 22
Terraform Modules & Remote State
Reusable module structure
Module inputs and outputs
Azure Blob remote state
Workspaces (dev / staging / prod)