Manual Test Runbook — H2: Conditional Access Bundle
Owner: Sagar | Time: ~5 min (Parts A + B, offline) · +30 min Part C (tenant apply + CA What-If simulation) | Sandbox: snowops-sandbox-tenant-01
Promotes H2 (
modules/azure/conditional-access/) from 🟦 Code Complete → 🟩 Shipped. Part C costs $0 (CA policies are P1/P2-license-only, no per-policy charge). Read carefully: H2 enforces MFA tenant-wide. Run in a sandbox tenant — never against a tenant where your own account is the sole break-glass.
Prerequisites
- Sandbox AAD tenant access (Conditional Access Administrator role active)
- H1 already applied in the same tenant (named locations + auth-strength policy available)
- Sandbox tenant has Microsoft Entra ID P1 minimum (P2 to test risk policies)
- A dedicated break-glass AAD group (
snowops-break-glass) with at least one PERMANENT Global Admin member who is NOT you. Verify before applying:az ad group member list --group snowops-break-glass --query '[].userPrincipalName' -o table - At least one tier-0 admin group (
snowops-tier0-admins) with a test user member - Local tooling:
terraform >= 1.6,go >= 1.22,az CLI >= 2.50,jq -
SNOWOPS_SANDBOX_TENANT_IDenv var set - Working directory: repo root
Steps
Part A — terraform fmt + validate (offline, ~2 min)
- Confirm formatting + structural validity of the module:
terraform -chdir=modules/azure/conditional-access fmt -check
terraform -chdir=modules/azure/conditional-access init -backend=false -input=false
terraform -chdir=modules/azure/conditional-access validate
Expected: Success!.
- Run the H2 offline Terratest case:
Expected: 1 top-level test passes.
Part B — full Terratest suite (offline, ~3 min)
- Run the whole offline suite:
Expected: 18 top-level tests pass.
Part C — tenant integration (real AAD apply + CA What-If, ~30 min)
H2 will provision 6 policies in
enabledstate by default. To rehearse safely, first apply inenabledForReportingButNotEnforced(Step 4), run the CA What-If simulator (Step 6), then re-apply withpolicy_state = "enabled"(Step 7).
- Capture the break-glass group + tier-0 admin group GUIDs:
export SNOWOPS_SANDBOX_TENANT_ID="<sandbox-tenant-guid>"
export SNOWOPS_BREAK_GLASS_GROUP_ID=$(az ad group show --group snowops-break-glass --query id -o tsv)
export SNOWOPS_TIER0_ADMINS_GROUP_ID=$(az ad group show --group snowops-tier0-admins --query id -o tsv)
- Apply in report-only mode first:
cd tests/terratest/fixtures/conditional-access
terraform init
terraform apply \
-var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID" \
-var "break_glass_group_object_id=$SNOWOPS_BREAK_GLASS_GROUP_ID" \
-var "tier0_admin_group_object_ids=[\"$SNOWOPS_TIER0_ADMINS_GROUP_ID\"]" \
-var 'policy_state=enabledForReportingButNotEnforced'
Spot-check the portal (Microsoft Entra ID → Security → Conditional Access → Policies): all 6 SnowOps policies present, state = "Report-only", each excludes the break-glass group.
- Run the CA What-If simulator for each policy. Per-policy URL:
https://entra.microsoft.com/#blade/Microsoft_AAD_IAM/ConditionalAccessBlade/PolicyDetails/policyId/<id>/whatIf. Simulate: - A regular user signing in from a US IP → policies 1 + 3 + 4 fire as expected (MFA + block-legacy + geo-allow); policy 2 doesn't apply.
- A tier-0 admin signing in from a US IP → policies 1 + 2 + 3 + 4 fire; grant requires phishing-resistant + compliant device.
- A regular user signing in from a KP IP → policy 4 fires (geo-block).
- The break-glass user signing in from any IP → no policy fires (excluded from all 6).
-
A high-risk sign-in (P2 only) → policy 5 fires (block).
-
Re-apply in enforce mode:
terraform apply \
-var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID" \
-var "break_glass_group_object_id=$SNOWOPS_BREAK_GLASS_GROUP_ID" \
-var "tier0_admin_group_object_ids=[\"$SNOWOPS_TIER0_ADMINS_GROUP_ID\"]"
Confirm portal state = "On" for all 6.
- Re-verify break-glass exclusion. Sign in as the break-glass user from
any IP and any device — sign-in must succeed without MFA. (If this
fails, immediately revert:
terraform apply -var 'policy_state=disabled'.)
Pass criteria
- Part A —
terraform validatepasses for the module - Part B — full offline Terratest suite passes (18 top-level tests)
- Part C Step 5 — all 6 policies present in report-only state
- Part C Step 6 — CA What-If results match the simulation matrix above
- Part C Step 7 — all 6 policies enforced
- Part C Step 8 — break-glass user signs in without MFA challenge
- All
Destroycalls complete without error
Teardown
cd tests/terratest/fixtures/conditional-access
terraform destroy \
-var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID" \
-var "break_glass_group_object_id=$SNOWOPS_BREAK_GLASS_GROUP_ID" \
-var "tier0_admin_group_object_ids=[\"$SNOWOPS_TIER0_ADMINS_GROUP_ID\"]"
Removes all 6 CA policies. The break-glass group + tier-0 admin group are NOT touched (out-of-band resources).
Sign-off
- Tester: _ | Date: _ | Result: PASS / FAIL / N/A
- Notes: