Manual Test Runbook — M3: Enforce TLS 1.2+ / HTTPS-only (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 M3 (
modules/azure/tls-policy/) from 🟦 Code Complete → 🟩 Shipped. Part C/D cost ~$0. M3 is validate-only in the automated suite — same pattern as M1/J2/H3/B5.
Prerequisites
- Sandbox subscription access active (PIM activated if required)
-
az logindone; sandbox subscription 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)
- ```bash terraform -chdir=modules/azure/tls-policy fmt -recursive -check terraform -chdir=modules/azure/tls-policy init -backend=false -input=false terraform -chdir=modules/azure/tls-policy validate
terraform -chdir=modules/azure/tls-policy/examples/basic init -backend=false -input=false terraform -chdir=modules/azure/tls-policy/examples/basic validate ```
Expected: Success! for both.
bash cd tests/terratest go test -v -timeout 5m ./modules/azure/... -run TestTLSPolicyValidate
Expected: PASS (exercises the effect + minimumTlsVersion dual-parameter threading on the storage_min_tls reference).
Part B — full Terratest suite (offline, ~3 min)
bash cd tests/terratest && go test -count=1 -timeout 15m ./...
Expected: 31 top-level tests green.
Part C — live apply, Audit mode first (sandbox, ~15 min, ~$0)
- Confirm the curated TLS built-in GUIDs resolve:
az policy definition list \
--query "[?policyType=='BuiltIn' && (contains(displayName,'TLS') || contains(displayName,'HTTPS') || contains(displayName,'secure transfer'))].{name:name, display:displayName}" -o table
- Apply in Audit mode:
cd modules/azure/tls-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 "effect=Audit" -var "minimum_tls_version=TLS1_2"
bash az policy assignment show --name snowops-tls \ --query "{effect:parameters.effect.value, minTls:parameters.minimumTlsVersion.value}" -o json
Expected: effect=Audit, minTls=TLS1_2.
Part D — Deny drill (optional, ~15 min)
- Flip to Deny:
terraform apply -auto-approve \
-var "subscription_id=$SNOWOPS_SANDBOX_SUBSCRIPTION_ID" \
-var "tenant_id=$SNOWOPS_SANDBOX_TENANT_ID" \
-var "effect=Deny" -var "minimum_tls_version=TLS1_2"
- Attempt a non-compliant create — a storage account with insecure transfer disabled (HTTP allowed). Allow a few minutes for propagation:
az group create -n m3-probe-rg -l eastus
az storage account create -n m3probe$RANDOM -g m3-probe-rg -l eastus \
--sku Standard_LRS --https-only false
Expected: denied with RequestDisallowedByPolicy (the
storage_secure_transfer reference). A --min-tls-version TLS1_0 create
should likewise be denied by storage_min_tls.
bash az group delete -n m3-probe-rg --yes --no-wait
Pass criteria
- Part A — module + example validate;
TestTLSPolicyValidatepasses - Part B — full offline suite passes (31 top-level)
- (Part C) assignment created; effect + minimumTlsVersion parameters set
- (Part D) an HTTP / TLS<1.2 create is denied under
effect = Deny - All test resources removed
Teardown
cd modules/azure/tls-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 m3-probe-rg --yes --no-wait # if Part D ran
Sign-off
- Tester: _ | Date: _ | Result: PASS / FAIL / N/A
- Notes: