We passed SOC 2 Type II with zero findings, zero qualifications, and almost no audit scrambling. Evidence collection that once took weeks was reduced to a single day. But the interesting part is this: we never built the platform for SOC 2. We built it to eliminate repetitive operational work — and compliance became inevitable.
Seven years ago, I was the only cloud engineer in the organisation. After provisioning the same Azure resources through the portal for the third time, the constraint was obvious: manual infrastructure doesn't scale consistently. That pushed me into Infrastructure as Code — first ARM templates, then Terraform. Leadership questioned why we were "writing code to create resources" when the portal already worked. That investment changed everything.
Here are the seven decisions that mattered most.
1. Terraform Became the Only Path to Production
No direct portal provisioning. Full stop.
Every infrastructure change flowed through Azure DevOps pipelines with approval gates, peer review, and a complete version history in Git. That single constraint solved a large portion of the change management and audit traceability requirements before we ever opened an audit framework document.
Auditors ask: "Can you show me every change made to your production environment in the last 12 months?" With pipeline-only deployments, the answer is a Git log and a pipeline run history. Without it, the answer is a week of manual reconstruction.
2. Compliance Was Built Into Modules, Not Engineer Memory
We stopped relying on engineers to "remember" security settings. Our Terraform modules enforced correct configuration structurally — if a resource was misconfigured, the module wouldn't deploy it.
# Storage module: compliance enforced at the module level
resource "azurerm_storage_account" "this" {
name = var.name
resource_group_name = var.resource_group_name
location = var.location
account_tier = "Standard"
account_replication_type = var.environment == "prod" ? "GRS" : "LRS"
# Always enforced — not optional
min_tls_version = "TLS1_2"
enable_https_traffic_only = true
allow_nested_items_to_be_public = false
blob_properties {
delete_retention_policy {
days = var.environment == "prod" ? 30 : 7
}
}
network_rules {
default_action = "Deny"
bypass = ["AzureServices"]
virtual_network_subnet_ids = var.allowed_subnet_ids
}
}
Private endpoints, TLS minimum versions, diagnostic logging, secure defaults, and environment-based retention policies were all codified. The module was the policy. Engineers didn't need to know the SOC 2 control set — they just used the approved modules.
3. Environments Were Explicitly Different by Design
Production, staging, and development should not be identical. We codified the differences — replication types, retention windows, resiliency tiers, network exposure — directly into module variables. var.environment == "prod" triggered stricter settings automatically.
This reduced both risk (dev misconfiguration can't mirror into prod patterns) and cost (no geo-redundant storage on dev workloads). It also made it trivially easy to demonstrate to auditors that production had stronger controls than lower environments.
4. Security Scanning Ran on Every Pull Request
Every infrastructure or application change passed through three tools before it could merge:
- tfsec — static analysis on Terraform for misconfigurations
- SonarCloud — code quality and security vulnerability scanning
- Snyk — dependency and container image vulnerability scanning
High-severity findings blocked merges automatically. Security review moved from a periodic, human-gated activity to continuous, automated enforcement. The audit evidence for "vulnerability management" was the pipeline run history — thousands of scans, blocking policy, remediation tracked in Git.
5. Centralised Logging Created a Single Source of Truth
Auditors always ask the same question: "Can you show me the logs?" The answer needs to be fast, complete, and unambiguous.
We centralised all diagnostic logs, activity logs, and security events into a single Log Analytics workspace. One query interface. One retention policy. One place to point auditors at. Evidence retrieval went from "we need to pull logs from six different services" to a single KQL query with an exportable result.
6. Continuous Compliance Monitoring Prevented Drift
Controls compliant at deployment can drift over time — a manual change here, a temporary exception that never got reversed. We used Vanta to continuously monitor that our controls remained in the state we declared them to be.
Instead of discovering drift during audit preparation, we saw it immediately. The audit wasn't a moment of reckoning — it was a confirmation of a state we'd been verifying continuously for 12 months.
7. We Treated IaC Modules Like Products
This was probably the highest-leverage decision of all.
Our modules weren't just infrastructure provisioning — they were opinionated, documented, versioned products that encoded how the platform was supposed to work. They had changelogs, READMEs, and breaking-change policies. Engineers extended and composed them rather than writing raw resources from scratch.
Over seven years, junior and intermediate engineers became genuinely effective because the modules guided them toward correct patterns. We operated without a dedicated DevOps hire for the entire period. The modules did that work.
Good modules don't just provision infrastructure. They teach the next engineer how the platform should work.
The Bigger Lesson
SOC 2 success wasn't the result of last-minute preparation or a compliance sprint. It was the side effect of consistent engineering discipline compounded over time.
The real goal was never "passing the audit." The goal was building systems where manual work was replaced by trustworthy, repeatable processes. Passing became inevitable because the controls were structural, not procedural.
If your team is approaching a first SOC 2 audit and feeling the weight of it, the honest answer is: you can't sprint your way to a well-governed platform. But you can start now, make the right structural decisions, and let time do the compounding.
I'm curious — what architectural or operational decision had the biggest long-term impact on your compliance journey? If you're working through this and want to talk it through, get in touch.