-
Notifications
You must be signed in to change notification settings - Fork 95
Testing and Validation
The project uses Terraform validation, security scans, OPA policy checks, and Terratest-style integration tests.
Sources:
| Layer | Tool | Purpose | Where it runs |
|---|---|---|---|
| Format | terraform fmt |
Consistent Terraform formatting | Local and CI |
| Static validation | terraform validate |
Valid Terraform syntax and provider graph | Local and CI |
| Security scan | tfsec | Terraform security checks | CI |
| Security scan | Checkov | Terraform security and compliance checks | CI |
| Secret scan | Gitleaks | Prevent committed secrets | CI |
| Policy as code | OPA/Rego | Enforce project-specific guardrails | CI |
| Lint | TFLint | Terraform lint and provider rules | CI advisory |
| Cost | Infracost | Cost estimate | CI advisory |
| Integration | Terratest | Verify deployed Azure resources | Optional/local or custom action |
Safe commands that do not deploy:
terraform fmt -check -recursive -diff
terraform init -backend=false
terraform validate -no-colorOptional local plan:
terraform init -backend=false
terraform plan -var-file=environments/cheap-lab.tfvarsFor remote-state plans, configure backend carefully and avoid committing backend config files.
Use these as rough pass indicators. Exact provider versions and timings can differ.
terraform fmt -check -recursive -diff
# no output means formatting is clean
terraform validate -no-color
Success! The configuration is valid.
If a command writes .terraform, lock files, or plan artifacts locally, do not commit generated files unless they are intentionally tracked by the repository.
Plan JSON is useful for regression checks:
terraform plan -var-file=environments/cheap-lab.tfvars -out=tfplan
terraform show -json tfplan > tfplan.jsonHigh-value checks:
| Check | Expected result |
|---|---|
| Public RDP | No broad 0.0.0.0/0 RDP path |
| LB RDP NAT | No RDP NAT rules by default |
| SQL | Public network access disabled when SQL is enabled |
| Key Vault | Network ACLs align with private-first intent |
| Storage | Public blob access disabled |
| Diagnostics | Deployed important resources have diagnostic settings |
| Tags | Required tags exist |
Test source: tests/landing_zone_test.go
Current tests:
| Test | What it checks |
|---|---|
TestLandingZoneDeployment/HubVNetExists |
Hub VNet exists |
TestLandingZoneDeployment/IdentityVNetExists |
Identity VNet exists |
TestLandingZoneDeployment/VNetPeeringConfigured |
Hub VNet has peerings |
TestKeyVaultAccessible/KeyVaultExists |
Key Vault exists in shared services resource group |
TestNetworkSecurityGroups/ManagementNSGExists |
Jumpbox NSG exists |
TestResourceTags/ResourceGroupHasTags |
Hub resource group has required tags |
The tests use:
| Variable | Purpose | Default |
|---|---|---|
ARM_SUBSCRIPTION_ID |
Azure subscription to query | Required or tests skip |
TEST_ENVIRONMENT |
Environment name used in resource naming | lab |
TEST_LOCATION_SHORT |
Location short code used in resource naming | wus2 |
Example:
$env:ARM_SUBSCRIPTION_ID = "<subscription-id>"
$env:TEST_ENVIRONMENT = "cheap-lab"
$env:TEST_LOCATION_SHORT = "wus2"
Set-Location tests
go test ./... -vIf Go is not installed, install Go before running Terratest locally. The CI can run Terratest through .github/actions/terratest once enabled in workflow.
Policy source:
OPA checks are run by .github/actions/policy-check.
Expected deny examples:
- Resource without tags.
- Storage account with public nested items access.
- Resource in a non-approved region.
- SQL server with public network access.
- Key Vault create without soft delete.
Expected warning examples:
- Public IP creation.
- Broad inbound NSG rule.
- Large VM SKU.
- VM without encryption at host.
Networking:
- Hub VNet exists.
- Spoke VNets exist for selected profile.
- Hub-to-spoke peerings exist.
- Route tables are associated.
- Firewall routes are present when firewall is enabled.
- App Gateway backend health is healthy when enabled.
Security:
- No public RDP unless intentionally enabled.
- Load Balancer RDP NAT rules are absent by default.
- Key Vault, Storage, and SQL public access match intended posture.
- Private Endpoint DNS resolves from spokes.
Monitoring:
- Log Analytics workspace exists.
- Diagnostics exist for deployed optional services.
- Alerts are scoped to real resource IDs.
- Flow logs are enabled only when intended.
Cost:
- Budget exists when cost management is enabled.
- Budget email recipients are real.
- Expensive resources are only enabled intentionally.
- Add unit-style tests for profile variable combinations.
- Add plan JSON tests for public RDP rejection.
- Add plan JSON tests for SQL public network access.
- Add tests for absence of LB RDP NAT by default.
- Add tests for Private Endpoint resources when enabled.
- Add tests for App Gateway backend pool input.
- Add CI job to run Terratest only against explicitly deployed test environments.
| Requirement | Evidence |
|---|---|
| Terraform syntax valid |
terraform validate output |
| Formatting clean |
terraform fmt -check -recursive -diff output |
| Security scans passed | tfsec, Checkov, Gitleaks job results |
| Policy gates passed | OPA policy-check job result |
| Cost reviewed | Infracost output or manual cost review |
| Plan reviewed | Plan add/change/destroy counts and resource diff |
| Deployment works | Apply job success and resource inventory |
| Environment works | Terratest and manual Azure checks |
| Scenario | Profile | Validation focus |
|---|---|---|
| Cheapest deployable learning path | cheap-lab |
No expensive edge services, no public RDP, core topology |
| Full lab build | lab |
Firewall, App Gateway, shared services, governance, monitoring |
| Development workload | dev |
Workload dev, AKS option, lower governance friction |
| Production-like review | prod |
Policy, secondary DC, VPN/on-prem simulation, stronger validation |
Good evidence:
- Includes the command or workflow run that produced it.
- Includes the selected profile and commit SHA.
- Shows pass/fail result, not just raw output.
- Redacts subscription IDs, tenant IDs, public IPs, object IDs, and secrets.
- Links back to the issue or Project item that required the validation.
Bad evidence:
- Screenshots with secrets or full identifiers.
- A statement that something was checked without output or screenshot.
- A plan generated from a different commit than the apply.
- A local-only result for a change that affects GitHub Actions or Azure RBAC.
Next page: Azure Portal Validation Evidence
- Architecture Overview
- Full Environment Inventory
- Network Topology
- Shared Services
- Workloads
- Module Reference
- Security Model
- Security Operations
- Identity and Access
- Governance and Policy
- Production Readiness Review
- Monitoring and Diagnostics
- Operations Runbooks
- Azure Portal Validation Evidence
- Cost Management
- Disaster Recovery and Resilience