Manual evidence collection is one of the most expensive and error-prone parts of any compliance program. Auditors request evidence. Someone digs through dashboards, exports CSVs, screenshots configurations, and compiles it all into a folder. Then the audit period ends, and six months later you do it again.
There's a better way — and it starts with treating your cloud infrastructure as a continuous evidence source rather than something you query only when auditors ask.
The problem with manual evidence
Manual evidence collection has three structural weaknesses:
- Point-in-time snapshots — evidence collected in November doesn't tell you whether controls were operating in February
- Human error — screenshots get mislabeled, exports have wrong date ranges, controls get confused
- Audit lag — by the time you're collecting evidence, the control may have drifted
Automated pipelines solve all three. Let's build one.
Architecture overview
The pipeline I built at Splunk uses three layers:
- AWS Systems Manager (SSM) — collects configuration state and patch compliance data from EC2 instances
- Splunk HEC (HTTP Event Collector) — ingests SSM outputs as structured events
- Splunk dashboards + scheduled searches — continuously map events to SOC 2 control requirements
The result: every night, the system generates a compliance posture report that maps directly to your SOC 2 control matrix. No manual collection required for the controls SSM covers.
Setting up SSM State Manager
SSM State Manager lets you define desired configuration states for your fleet and continuously assess whether instances conform. For compliance purposes, the most valuable associations are:
# Example SSM Association for patch compliance
aws ssm create-association \
--name "AWS-GatherSoftwareInventory" \
--targets "Key=tag:Environment,Values=production" \
--schedule-expression "rate(1 day)" \
--parameters '{"applications":["Enabled"],"networkConfig":["Enabled"]}'
For SOC 2 CC6.1 (logical access controls), you can use SSM to collect IAM configuration data. For CC7.1 (change detection), SSM Inventory gives you a continuous baseline of installed software, network configurations, and running services.
Shipping to Splunk via HEC
Once SSM is collecting data, a Lambda function fires on EventBridge to ship the data to Splunk:
import json, boto3, urllib.request
def lambda_handler(event, context):
ssm = boto3.client('ssm')
# Pull latest compliance summary
response = ssm.list_compliance_summaries()
payload = json.dumps({
"time": int(__import__('time').time()),
"sourcetype": "aws:ssm:compliance",
"event": response['ComplianceSummaryItems']
})
req = urllib.request.Request(
"https://your-splunk-hec-endpoint/services/collector",
data=payload.encode(),
headers={"Authorization": "Splunk YOUR_HEC_TOKEN"},
method="POST"
)
urllib.request.urlopen(req)
Mapping to SOC 2 controls in Splunk
The real value is in the search layer. A saved search like this generates continuous evidence for CC6.8 (malicious software prevention):
index=compliance sourcetype="aws:ssm:compliance"
| where ComplianceType="Patch"
| stats count(eval(Status="COMPLIANT")) as compliant,
count(eval(Status="NON_COMPLIANT")) as non_compliant by ResourceId
| eval compliance_rate=round((compliant/(compliant+non_compliant))*100,1)
| where compliance_rate < 95
| table ResourceId, compliance_rate, non_compliant
Schedule this search daily. Alert on drift. Export results quarterly to your audit evidence folder automatically using Splunk's scheduled PDF export.
Controls this pipeline covers
A well-configured SSM + Splunk pipeline can produce continuous evidence for roughly 15–20% of a typical SOC 2 control set — particularly across CC6, CC7, and A1 (availability). That's not everything, but it's the part that historically consumes the most manual effort.
What this doesn't replace
Automated evidence is a floor, not a ceiling. Auditors still need to understand why controls exist and how exceptions are managed. The automation handles the "did this happen" question. You still need humans to answer "does this control design make sense" and "how did you respond when it failed."
Build the pipeline, then build the narrative around it.