Skip to content

Manual Test Runbook — U1: Subscription Budget + Alerts

Owner: Sagar  |  Time: ~10 min (Parts A + B) · +5 min (optional Part C integration) · +15 min (optional Part D alert walkthrough)  |  Sandbox: snowops-sandbox-01

Promotes U1 (modules/azure/budget-alert/) from 🟦 Code Complete → 🟩 Shipped. Part C (the build-tagged integration test) creates a budget + action group and tears them down (~$0 — budgets + action groups are free). Part D is a walkthrough of how an alert fires; a real cost-spike can't be triggered on demand in a sandbox (spend has to accrue past the threshold), so the drill lowers a threshold / inspects the forecast rather than burning money.


Prerequisites

  • Sandbox subscription access active (PIM activated if required)
  • az login done; az account show confirms the sandbox subscription is selected
  • Sandbox SP / identity has Contributor on the sandbox sub
  • SNOWOPS_SANDBOX_SUBSCRIPTION_ID + SNOWOPS_SANDBOX_TENANT_ID exported
  • Local tooling: terraform >= 1.6, go >= 1.22, az CLI >= 2.50
  • Working directory: repo root

Steps

Part A — terraform fmt + validate (offline, ~3 min)

  1. Module + example:
terraform -chdir=modules/azure/budget-alert fmt -recursive -check
terraform -chdir=modules/azure/budget-alert init -backend=false -input=false
terraform -chdir=modules/azure/budget-alert validate

terraform -chdir=modules/azure/budget-alert/examples/basic init -backend=false -input=false
terraform -chdir=modules/azure/budget-alert/examples/basic validate

Expected: Success! The configuration is valid. for both.

  1. Offline Terratest case:
cd tests/terratest
go test -v -timeout 5m ./modules/azure/... -run TestBudgetAlertValidate

Expected: PASS.

Part B — full Terratest suite (offline, ~3 min)

  1. bash cd tests/terratest go test -count=1 -timeout 15m ./...

Expected: full offline suite green (35 top-level tests across all packages).

Part C — integration test: budget + action group apply/destroy (sandbox, ~5 min, ~$0)

  1. Run the build-tagged integration test (creates a unique RG + action group + Monthly budget with 50/80/100 actual + 100 forecasted notifications + a CostCenter tag filter, asserts shape, destroys):
cd tests/terratest
go test -v -tags integration -timeout 30m ./modules/azure/... -run TestBudgetAlertModule

Expected: PASS. Asserts the budget ARM ID under the sub, the created action group ID, the four notification keys, and recipient_count >= 1.

Part D — alert walkthrough (optional, ~15 min)

A real cost-spike alert can't be triggered on demand (spend must accrue past the threshold). This part confirms the budget + notifications are wired correctly so an alert WOULD fire, and shows how to force-test recipient delivery.

  1. Apply the example with a real recipient email + the subscription Owners:
cd modules/azure/budget-alert/examples/basic
terraform init -input=false
terraform apply -auto-approve \
  -var "subscription_id=$SNOWOPS_SANDBOX_SUBSCRIPTION_ID" \
  -var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID" \
  -var "amount=10" \
  -var "start_date=$(date -u +%Y-%m-01T00:00:00Z)" \
  -var 'contact_emails=["YOUR_EMAIL@example.com"]'
  1. Confirm the budget + its notifications:
az consumption budget show --budget-name snowops-example-budget \
  --query "{name:name, amount:amount, grain:timeGrain, notifications:keys(notifications)}" -o json

Expected: budget present; amount 10; Monthly; notification keys for each threshold.

  1. (Optional, if you wired an action group via create_action_group) Test recipient delivery directly without waiting for spend:
az monitor action-group test-notifications create \
  --action-group-name <AG_NAME> --resource-group <RG> \
  --alert-type budget --email-receiver name=finops emailAddress=YOUR_EMAIL@example.com

Expected: a test notification email arrives.

  1. (Inspect) Lower a threshold close to current month-to-date spend (or note the forecasted threshold) and confirm in the portal that the budget's alert condition is satisfied — Azure evaluates budgets ~every 8–24h, so a live alert email is not instant.

Pass criteria

  • Part A — module + example validate; TestBudgetAlertValidate passes
  • Part B — full offline Terratest suite passes (35 top-level)
  • (Part C) TestBudgetAlertModule applies the budget + action group and destroys clean
  • (Part D) budget + notifications present; test-notification email delivered (if action group wired)
  • All test resources removed

Teardown

# Part C cleans up after itself (deferred terraform destroy).
# Part D (if run):
cd modules/azure/budget-alert/examples/basic
terraform destroy -auto-approve \
  -var "subscription_id=$SNOWOPS_SANDBOX_SUBSCRIPTION_ID" \
  -var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID"

Sign-off

  • Tester: _  |  Date: _  |  Result: PASS / FAIL / N/A
  • Notes: