35-Day DevOps Bootcamp ยท Day 22
1 / 16
Terraform Deep Dive
Day 22: Terraform - Resources, Variables, State & Modules
Real Azure/AWS resources, variable types, outputs, locals, and remote state
โฑ 60 min ๐Ÿ“– Theory (35 min) ๐Ÿ”ง Lab (20 min) โ“ Quiz (5 min)

Resources

Understand create/update/destroy/no-op behavior and lifecycle planning.

Inputs/Outputs

Use variables, locals, outputs, and data sources correctly.

State

Move from local state to remote state with locking for team safety.

Session Plan
Theory, Lab, and Quiz Breakdown

๐Ÿ“– Theory

Terraform Resource Lifecycle (create/update/destroy/no-op)
Variables, Locals, Outputs, and Data Sources
State Fundamentals and Remote State Backends

๐Ÿ”ง Lab

Provision Azure + GitHub resources and build a reusable module, then review `plan` vs `apply` behavior.

โ“ Quiz

5-minute knowledge check on lifecycle, locals, outputs, and remote state.

Core Concept
Terraform Resource Lifecycle
Terraform compares desired state (`.tf`) with current state (`.tfstate`).

create

Resource exists in config but not in state.

update

Resource exists in both, but configuration changed.

destroy

Resource exists in state but was removed from config.

no-op

Resource exists in both and is unchanged, so nothing happens.

Workflow
How Terraform Decides Actions

1) Read Config

Parse `.tf` files as desired state.

2) Read State

Load current state from backend.

3) Diff

Compute action graph for each resource.

4) Execute

`plan` previews, `apply` performs changes.

terraform init terraform plan terraform apply
Inputs and Outputs
Variables, Locals, Outputs, Data Sources

variable

Input values set via CLI, env vars, or `.tfvars`.

locals

Computed values inside the module (not external inputs).

output

Expose values to users or other modules.

data source

Read existing infrastructure not managed by this Terraform config.

Best Practice
Use Locals to Avoid Repetition
If an expression appears 3+ times, move it to `locals`.
variable "env" { type = string } variable "project" { type = string } locals { common_tags = { env = var.env project = var.project } } resource "azurerm_resource_group" "main" { name = "${var.project}-${var.env}-rg" location = "Central India" tags = local.common_tags }
State
State File Essentials

What state does

Maps configured resources to real infrastructure IDs and attributes.

Risk

State can include sensitive values. Never commit local state to Git.

Single source of truth

Terraform plans and applies depend on accurate, consistent state.

Team impact

Local state breaks collaboration and causes drift/conflicts.

Team Workflows
Remote State Backends + Locking

Azure

`azurerm` backend using Blob Storage.

AWS

`s3` backend (with locking setup for team safety).

Terraform Cloud

Managed state + locking, free tier available.

State Locking (Critical)

Prevents concurrent `terraform apply` from multiple users and avoids state corruption.

Hands-on Labs
Hands-on Labs: Azure + GitHub + Modules

Lab A - Provision Azure Resources

Step 1: Configure Azure provider and backend (if remote state is enabled).
Step 2: Create resource group + storage account using variables.
Step 3: Run `terraform init`, `terraform plan`, `terraform apply`.
resource "azurerm_resource_group" "rg" { name = "${var.project}-${var.env}-rg" location = var.location tags = local.common_tags } resource "azurerm_storage_account" "st" { name = "${var.project}${var.env}st01" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" account_replication_type = "LRS" }

Lab B - Provision GitHub Repository

Step 1: Configure GitHub provider (`integrations/github`).
Step 2: Set `TF_VAR_github_token` securely in your shell.
Step 3: Run `terraform init`, `terraform plan`, `terraform apply`.
terraform { required_providers { github = { source = "integrations/github" version = "~> 6.0" } } } provider "github" { token = var.github_token } resource "github_repository" "labs_repo" { name = "terraform-day22-labs" visibility = "private" auto_init = true }

Lab C - Build and Use a Module

Step 1: Create child module: `modules/resource_group`.
Step 2: Add `main.tf`, `variables.tf`, `outputs.tf` in that module.
Step 3: Call the module from root and pass inputs.
module "rg" { source = "./modules/resource_group" name = "${var.project}-${var.env}-rg" location = var.location tags = local.common_tags } output "resource_group_name" { value = module.rg.name }
Quiz
5-Minute Knowledge Check
1) What triggers `create` vs `update` in Terraform?
2) When should you use `locals` instead of `variables`?
3) What is the purpose of an `output` block?
4) Why is remote state locking important for teams?
5) What is the difference between a `resource` and a `data` source?
Recap
Day 22 Summary
Terraform lifecycle: create, update, destroy, no-op.
Variables are inputs, locals are computed values, outputs expose values.
Data sources read existing infrastructure without managing it.
Remote state + locking is mandatory for safe team workflows.

Next Practice

Extend the lab with a reusable module and compare plans across dev/staging workspaces.

Additional Session
Terraform Modules
Reusable modules, module registry, workspaces, and Terragrunt intro
โฑ 60 min ๐Ÿ“– Theory ๐Ÿ”ง Lab: Build and Use a Terraform Module โ“ Quiz: 5 min

๐Ÿ“– Theory Topics

What is a Terraform Module? (root module vs child module)
Module structure + module registry usage
Workspaces, environment strategy, and Terragrunt intro
Modules Basics
What is a Terraform Module?

Module Definition

A module is a reusable package of Terraform resources. Every Terraform configuration is a module.

Root Module

The directory where you run Terraform commands (`init`, `plan`, `apply`).

Child Module

Invoked from root using a `module` block and input variables.

Module Sources

Public registry (`registry.terraform.io`) or private/internal module repos/registries.

Practical Advice

Do not build everything from scratch. Start with official battle-tested modules such as Azure AKS, AWS VPC, or GCP GKE.

Module Design
Recommended Module Structure
modules/network/ main.tf # resource definitions variables.tf # input variable declarations outputs.tf # output value declarations README.md # usage docs and examples

main.tf

Contains the resources and data sources used by the module.

variables.tf

Declares typed inputs with defaults/validation where needed.

outputs.tf

Exposes IDs/attributes for root or downstream modules.

README.md

Document usage, examples, inputs, outputs, and constraints.

Automation Tip

Use `terraform-docs` to auto-generate README input/output documentation from your module code.

Environments
Workspaces and Terragrunt Intro
terraform workspace new staging terraform workspace select production

Workspaces

Allow multiple environments with same config; each workspace has its own state file.

Large Team Strategy

Separate directories per environment is usually clearer and preferred for large teams.

Terragrunt Intro

Wrapper tool for DRY config, environment orchestration, and reusable module wiring.

When to Use

Useful when managing many stacks/accounts/regions with repeated backend/provider config.

Modules Lab + Quiz
Build and Use a Terraform Module

๐Ÿ”ง Lab Flow

Create a child module (`modules/resource_group`).
Define `variables.tf`, `main.tf`, `outputs.tf`.
Call module from root and pass env/project/location variables.
Run `terraform init`, `terraform plan`, `terraform apply`.

โ“ 5-Min Quiz Prompts

1) Root module vs child module difference?
2) Why split module files into main/variables/outputs?
3) Why can workspace strategy be risky for very large teams?
4) When should you adopt Terragrunt?