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 logindone;az account showconfirms the sandbox subscription is selected - Sandbox SP / identity has Contributor on the sandbox sub
-
SNOWOPS_SANDBOX_SUBSCRIPTION_ID+SNOWOPS_SANDBOX_TENANT_IDexported - 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)
- 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.
- Offline Terratest case:
Expected: PASS.
Part B — full Terratest suite (offline, ~3 min)
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)
- 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.
- 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"]'
- 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.
- (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.
- (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;
TestBudgetAlertValidatepasses - Part B — full offline Terratest suite passes (35 top-level)
- (Part C)
TestBudgetAlertModuleapplies 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: