Skip to content

Repository files navigation

Azure FinOps Lab

Terraform AzureRM AzAPI License

Azure FinOps Lab banner

Azure FinOps Lab is a Terraform-first cost optimization sandbox for learning how to control Azure spend before, during, and after deployment. It creates a small workload plus the FinOps controls around it: budgets, alerts, tags, policy, Cost Management exports, Infracost checks, auto-shutdown, dashboards, and evidence capture.

The default profile is intentionally low cost. The lab gives you enough Azure infrastructure to measure and optimize without deploying expensive platform services.

Architecture

Azure FinOps Lab architecture

Area What it deploys Why it matters
Platform resource group Log Analytics, action group, cost export storage, dashboard, workbook Central place for cost visibility and evidence.
Workload resource group Small Windows IIS VM, VNet, subnet, NSG, public IP A real workload for rightsizing, shutdown, and tag exercises.
Budgets Subscription and workload resource group budgets Shows actual and forecasted cost thresholds.
Policy Required tag audit and allowed VM SKU audit Teaches governance without blocking labs by default.
Cost export Scheduled subscription actual-cost export to Storage Builds the reporting pipeline for offline analysis.
CI/CD Terraform validation, security checks, Infracost, manual lifecycle Teaches FinOps controls before apply.

Master Control Panel

FinOps feature toggle control panel

deploy_budgets       = true
deploy_tag_policy    = true
deploy_cost_export   = true
deploy_workload_vm   = true
deploy_monitoring    = true
deploy_auto_shutdown = true
deploy_dashboards    = true

monthly_subscription_budget_amount = 150
monthly_lab_rg_budget_amount       = 50
policy_effect                      = "Audit"
vm_size                            = "Standard_B1s"
auto_shutdown_time                 = "1900"

Keep policy_effect = "Audit" for workshops. Move to Deny only after validating the lab and explaining the blast radius.

Deployment Profiles

Profile File Purpose Default posture
Dev environments/dev.tfvars Fast validation with no Cost Management export. Lowest cost
Lab environments/lab.tfvars Main workshop profile with budgets, export, workload, and dashboards. Recommended
Full environments/full.tfvars Bigger comparison VM budget and SKU for rightsizing discussions. Higher cost

Quick Start

Prerequisites:

  • Terraform 1.9 or later
  • Azure CLI
  • PowerShell 7+
  • Azure permissions for resource groups, budgets, policy assignments, and Cost Management exports
az login
az account set --subscription "<subscription-id>"

Copy-Item terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with subscription_id, owner, budget_contact_emails, admin_source_ip_cidr,
# budget_start_date for the current month, and cost_export_start_date to a future date.

.\scripts\Test-FinOpsLabStatic.ps1
terraform init
terraform plan -var-file="environments/lab.tfvars"

Apply, smoke test, and destroy:

.\scripts\Invoke-FinOpsLabLifecycle.ps1 -Environment lab -Apply -SmokeTest -Destroy -AutoApprove

Lab Scenarios

Azure FinOps Lab scenarios

Scenario What you practice
Budget guardrails Configure subscription and resource group budgets with actual and forecasted thresholds.
Tag governance Audit missing cost tags and discuss when to move from Audit to Deny.
Infracost PR review Review cost deltas before infrastructure changes merge.
Auto-shutdown Reduce compute cost using Dev/Test VM shutdown schedules.
Rightsizing Compare VM SKU choices and capture Advisor-style optimization evidence.
Cost export Export actual costs for reporting and Power BI or spreadsheet analysis.
Dashboard evidence Use the portal dashboard, workbook, and scripts to collect proof of controls.

Cost And Safety Notes

  • The VM is the only default compute workload and uses Standard_B1s.
  • Azure budgets and policies are subscription-scope controls; use a lab subscription when learning.
  • Cost export availability can vary by billing setup. If your tenant blocks it, set deploy_cost_export = false.
  • admin_source_ip_cidr defaults to 0.0.0.0/32, which is intentionally not a useful public RDP source.
  • Terraform state contains generated VM credentials. Keep state private and never commit local state.
  • Destroy the lab after practice unless you are intentionally collecting cost data over time.

Documentation

Start here Purpose
Wiki home Map of the full documentation set.
Book-style guide End-to-end explanation of the lab and learning path.
Architecture overview Resource layout and data flow.
Scenarios Hands-on exercises.
Apply, smoke, destroy runbook Exact live-lab sequence.
Variables Input reference and recommended defaults.
Troubleshooting Common permissions and deployment issues.

Validation

terraform fmt -check -recursive
terraform init -backend=false -reconfigure
terraform validate

Optional tools:

tflint --init
tflint --recursive
checkov -d . --framework terraform
gitleaks detect --source . --redact

Project Structure

Azure-FinOps-Lab/
|-- main.tf
|-- variables.tf
|-- outputs.tf
|-- environments/
|-- modules/
|-- scripts/
|-- docs/images/
|-- wiki/
`-- .github/workflows/

License

MIT. See LICENSE.

About

Azure FinOps and cost optimization lab with Terraform, budgets, policy, Infracost, smoke tests, and safe destroy flow.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages