compliance.tf

B2B SaaS Starter Kit: SOC 2

For B2B SaaS companies heading toward SOC 2 Type I or II. Deploys the infrastructure layer your auditor will ask about: encrypted databases, private subnets, HTTPS-only endpoints, access logging, Multi-AZ data stores.

GitHub: compliancetf/starter-kit-saas-soc2

Registry: soc2.compliance.tf

Resources deployed: approximately 107


Architecture

SOC 2 SaaS infrastructure architecture

The architecture covers the typical SaaS application layer: a public-facing ALB with WAF, a private EKS cluster, an Aurora PostgreSQL database in dedicated database subnets, and shared services (S3, DynamoDB, ElastiCache, SQS). VPC flow logs and CloudWatch log groups are included for CC7.1.


Module Inventory

ModuleVersionPurposeKey SOC 2 Controls
vpc~> 6.0Network isolation, flow logs, database subnetsCC6.1, CC7.1
alb~> 10.0HTTPS load balancing, access logsCC6.6, CC6.7
waf~> 1.0Web Application Firewall (OWASP Top 10, IP reputation)CC6.6
acm~> 6.0TLS certificate (DNS-validated)CC6.7
kms~> 4.0Customer-managed key for EKS log encryptionCC6.1
eks~> 21.0Kubernetes cluster, private subnets, KMS-encrypted logsCC6.1, CC7.1
rds_aurora~> 10.0Aurora PostgreSQL, Multi-AZ, encrypted, IAM authCC6.1, A1.2
s3_bucket_data~> 5.0Application data, cross-region replicationCC6.1, CC7.2, A1.2
s3_bucket_logs~> 5.0Centralized access logs (ALB + S3), cross-region replicationCC7.1, CC8.1, A1.2
dynamodb~> 5.0Key-value store, PITRCC6.1, A1.2
elasticache~> 1.0Redis, encrypted at rest and in transit, auth, failoverCC6.1, A1.2
sqs~> 5.0Message queue, DLQCC6.1, CC7.2
cloudwatch~> 5.0Application log groupCC7.1, CC7.2

Quick Start

Prerequisites: Terraform >= 1.3, AWS credentials, a compliance.tf account, a Route 53 hosted zone, and an S3 replication IAM role + destination bucket for cross-region replication (required for SOC 2 A1.2).

git clone https://github.com/compliancetf/starter-kit-saas-soc2.git
cd starter-kit-saas-soc2

cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars: set project_name, domain_name, route53_zone_id,
# availability_zones, s3_replication_role_arn, s3_replication_destination_bucket_arn

terraform login soc2.compliance.tf

terraform init
terraform plan
terraform apply

terraform plan fails if any SOC 2 control is violated. The error names the specific control and the module that triggered it. Fix the issue and re-run.


SOC 2 Control Coverage

SOC 2 CriterionDescriptionModule(s)What's Enforced
CC6.1Logical access securityKMS, RDS Aurora, S3, EKS, ElastiCache, DynamoDB, SQSEncryption at rest, customer-managed keys, no public access, IAM authentication
CC6.6Logical access security measures against threats from outside system boundariesALB, WAFTLS 1.2+ (TLS 1.3 policy), HTTPS-only, WAF with OWASP Top 10 and IP reputation rules
CC6.7Restriction of data transmission to authorized users and processesALB, ElastiCacheHTTPS-only listeners, transit encryption enabled
CC7.1Detection of configuration changes that introduce vulnerabilities and susceptibilities to newly discovered vulnerabilitiesVPC, ALB, RDS Aurora, CloudWatch, S3 (logs)VPC flow logs, ALB access logs, PostgreSQL log exports, CloudWatch log groups
CC7.2Monitoring of system components and controls on an ongoing basis to detect anomalies indicating malicious acts or errorsS3, SQS, CloudWatchS3 versioning, dead-letter queues, log retention policies
CC8.1Change management controlsAll modulesInfrastructure changes tracked in Terraform state and version control, deletion protection (prod)
A1.2Data backup processes, recovery infrastructure, and environmental protectionsRDS Aurora, ElastiCache, S3 (data + logs)Multi-AZ deployment, automatic failover, automated backups (7-14 days), S3 cross-region replication

What compliance.tf Covers vs. What You Own

compliance.tf enforces the infrastructure controls in SOC 2. The table below shows the split.

What this kit handles

  • Encryption at rest and in transit for all data stores
  • S3 cross-region replication (SOC 2 A1.2 data durability)
  • Network isolation: private subnets, database subnets, no public database access
  • TLS 1.2+ on all external endpoints, enforced by the registry at plan time
  • Access logging: VPC flow logs, ALB access logs, Aurora PostgreSQL logs
  • Multi-AZ and automated backups
  • Deletion protection in production (environment = "prod")
  • Validation at terraform plan; non-compliant configurations fail before deployment

What you own

  • Application-level authentication, authorization, and session management
  • Identity provider configuration and MFA enforcement
  • HR policies: background checks, security awareness training
  • Vendor management and third-party risk assessments
  • Incident response procedures and runbooks
  • Business continuity planning
  • Access reviews and user lifecycle management
  • Application-level audit logging for business events

compliance.tf does not replace a SOC 2 auditor. It covers the infrastructure controls. The audit will still cover organizational controls (HR policies, access reviews, incident response, vendor management) but not whether Aurora is encrypted or S3 blocks public access.


Vanta and Drata Integration

compliance.tf evidence maps directly to the categories that Vanta and Drata check automatically.

Compliance Platform CheckSOC 2 CriterionWhat compliance.tf Enforces
Encryption at rest (databases)CC6.1RDS Aurora, DynamoDB, ElastiCache, S3 encrypted with KMS
HTTPS enforced on load balancersCC6.6, CC6.7ALB HTTPS-only listener, TLS 1.2+ policy
S3 buckets not publicly accessibleCC6.1S3 module blocks all public access by default
RDS not publicly accessibleCC6.1Aurora deployed in private database subnets, no public endpoint
VPC flow logs enabledCC7.1VPC module enables flow logs by default
Multi-AZ for RDSA1.2Aurora writer + reader across multiple availability zones
S3 versioning enabledCC7.2S3 data bucket has versioning enabled by default

For evidence collection, point your compliance platform at the Terraform state or the AWS resource tags. All modules in this kit tag resources with Project, Environment, and ManagedBy = "terraform" so resources are easy to scope during evidence gathering.

CloudTrail is not in this kit

Vanta and Drata both check for CloudTrail, which is account-wide. Enable CloudTrail at the account level separately; it is not a module-level control. The compliance.tf get started guide covers account-level prerequisites.


Common Customizations

Swap EKS for ECS

Remove the eks module block from main.tf and replace it with the ecs module from soc2.compliance.tf. Update the ALB target group to point at your ECS service instead of EKS pods.

module "ecs" {
  source  = "soc2.compliance.tf/terraform-aws-modules/ecs/aws"
  version = "~> 5.0"

  cluster_name = local.name

  fargate_capacity_providers = {
    FARGATE = {
      default_capacity_provider_strategy = {
        weight = 100
      }
    }
  }

  tags = var.tags
}

Add a second region for disaster recovery

S3 cross-region replication is already configured for the data and logs buckets via the s3_replication_role_arn and s3_replication_destination_bucket_arn variables. To extend DR to compute and database layers, use a second provider alias and duplicate the relevant module blocks:

provider "aws" {
  alias  = "dr"
  region = "us-west-2"
}

Use Aurora Global Database for database replication across regions.

Adjust instance sizes

All instance sizes are variables. Override them in terraform.tfvars:

eks_node_instance_types = ["m6i.xlarge"]
eks_node_min_size       = 3
eks_node_max_size       = 10

aurora_instance_class   = "db.r6g.xlarge"
redis_node_type         = "cache.r6g.large"

Remove a module you don't need

If your application does not use DynamoDB or SQS, delete those module blocks from main.tf and remove the corresponding outputs. The remaining modules are independent; removing one does not break others.

Disable a specific control

If a SOC 2 control does not apply to your use case, disable it with a query parameter on the module source:

module "s3_bucket_data" {
  source  = "soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws?disable=s3_bucket_object_lock_enabled"
  version = "~> 5.0"
  # ...
}

Cost Estimate

ComponentDevProd
VPC + NAT Gateway~$35~$100
ALB~$25~$25+
EKS control plane~$75~$75
EKS nodes (t3.medium)~$60~$120+
Aurora PostgreSQL (db.r6g.large)~$200~$400
S3 (data + logs)~$5~$5+
DynamoDB (on-demand)~$0~$0+
ElastiCache (cache.t4g.micro)~$10~$20
SQS~$0~$0+
CloudWatch Logs~$5~$10+
WAF~$5~$5+
KMS~$1~$1+
Total~$500-800~$1,500-2,500

Actual costs depend on usage, data transfer, and region. Use Infracost to get an estimate from your actual terraform plan output.


Next Steps

On this page

Ask AI about this

Help improve this page