Manual Test Runbook — U2: Require Mandatory Tags (Azure Policy)
Owner: Sagar | Time: ~10 min (Parts A + B) · +15 min (optional Part C live apply) · +15 min (optional Part D Deny drill) | Sandbox: snowops-sandbox-01
Promotes U2 (
modules/azure/tag-policy/) from 🟦 Code Complete → 🟩 Shipped. Part C/D cost ~$0 (policy assignments are free; the drill creates and deletes a single resource group). U2 is validate-only in the automated suite — a live apply mutates the subscription's policy state, so the apply + Deny drill are manual here (same pattern as M6/N5/J2/H3/B5). The "Require a tag" built-ins are Deny-only, so the rollout knob isenforce = false → true(no Audit effect).
Prerequisites
- Sandbox subscription access active (PIM activated if required)
-
az logindone;az account showconfirms the sandbox subscription is selected - Identity has Owner OR Resource Policy Contributor on the sandbox sub
- 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/tag-policy fmt -recursive -check
terraform -chdir=modules/azure/tag-policy init -backend=false -input=false
terraform -chdir=modules/azure/tag-policy validate
terraform -chdir=modules/azure/tag-policy/examples/basic init -backend=false -input=false
terraform -chdir=modules/azure/tag-policy/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 — live apply, rollout (enforce=false) mode first (sandbox, ~15 min, ~$0)
- Verify the curated default built-in GUIDs resolve in your tenant:
az policy definition list \
--query "[?policyType=='BuiltIn' && contains(displayName,'Require a tag')].{name:name, display:displayName}" -o table
If a curated default is missing/renamed, pass a corrected var.resource_tag_policy_id.
- Apply the example in rollout mode (
enforce = false— never blocks unrelated sandbox resources):
cd modules/azure/tag-policy/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 "enforce=false"
- Confirm the initiative + assignment exist and the per-tag references are present:
az policy assignment show --name snowops-mandatory-tags \
--query "{name:name, enforcement:enforcementMode}" -o json
az policy set-definition show --name snowops-mandatory-tags \
--query "policyDefinitions[].policyDefinitionReferenceId" -o tsv
Expected: assignment present, enforcementMode = DoNotEnforce; reference IDs
resource/Environment, resource/Owner, … and rg/Environment, … listed.
Part D — Deny drill (optional, ~15 min)
Proves the catalog criterion: "untagged create denied." Re-apply with
enforce = true, then attempt a create with a tag missing.
- Flip to enforce:
terraform apply -auto-approve \
-var "subscription_id=$SNOWOPS_SANDBOX_SUBSCRIPTION_ID" \
-var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID" \
-var "enforce=true"
- Attempt to create a resource group WITHOUT the mandatory tags (the
rg/*references should block it). Allow a few minutes for the assignment to take effect:
Expected: the create is denied with a RequestDisallowedByPolicy error
naming the SnowOps mandatory-tags initiative. (If it succeeds, the assignment
has not propagated yet — retry after ~5–10 min.)
- Confirm a fully-tagged create succeeds:
az group create -n u2-ok-rg -l eastus \
--tags Environment=sandbox Owner=sagar CostCenter=platform Compliance=SOC2 Client=internal
Expected: succeeds.
-
Cleanup the probes:
Pass criteria
- Part A — module + example validate;
TestTagPolicyValidatepasses - Part B — full offline Terratest suite passes (35 top-level)
- (Part C) assignment created in DoNotEnforce mode; per-tag references present
- (Part D) an untagged RG create is denied under
enforce = true; a fully-tagged create succeeds - All test resources removed; no orphaned probe RGs
Teardown
cd modules/azure/tag-policy/examples/basic
terraform destroy -auto-approve \
-var "subscription_id=$SNOWOPS_SANDBOX_SUBSCRIPTION_ID" \
-var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID"
az group delete -n u2-ok-rg --yes --no-wait 2>/dev/null || true # if Part D ran
Destroying the assignment stops future tag enforcement; resources created while it was active are unaffected.
Sign-off
- Tester: _ | Date: _ | Result: PASS / FAIL / N/A
- Notes: