Sign in
Menu
Start free trial
Annex A: SOC 2

SOC 2 controls built into your Terraform modules. Enforced before apply.

Your SOC 2 audit asks for encryption, logging, access controls and versioning on AWS resources. The modules enforce these controls before apply and list the Trust Services Criteria clause each one maps to, where the catalog names one.

Modules enforce 94 of 140 SOC 2 controls in the catalog. Of the 121 that cite a SOC 2 clause, they enforce 80. The controls they do not enforce stay with your team, with policies, training, vendor reviews and incident response.

No credit card or AWS account needed to start. By Anton Babenko, maintainer of terraform-aws-modules, more than 2 billion provisions.

Annex A: SOC 2

Framework
SOC 2, Trust Services Criteria
For
Your team, on Terraform
A.1

Scope for SOC 2

If you sell software or cloud services to other businesses, their procurement teams ask for a SOC 2 report, often before they sign.

A.1.1

Covers

  • Infrastructure controls on AWS resources that map to Trust Services Criteria clauses, by clause family in A.3.
  • terraform-aws-modules through the SOC 2 framework host or your org endpoint, and resources written by hand outside modules once your team switches to the compliance.tf provider.
A.1.2

Stays with your team

  • Organizational policies and procedures.
  • Employee background checks and security training.
  • Change management procedures and approval workflows.
  • Vendor management and third-party risk assessments.
  • Incident response and communication plans.
  • Business continuity and disaster recovery testing.
  • Resources outside compliance.tf module coverage, and every control A.4 lists as Mapped: 41 with a SOC 2 clause and 5 without one.
A.2

The source line

Point a module at the SOC 2 framework host. Same inputs and outputs, no state migration. Terraform 1.0 or later.

-  source  = "terraform-aws-modules/s3-bucket/aws"
+  source  = "soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws"
   version = "~> 5.0"

With an org endpoint, the source names your org host instead, and SOC 2comes from your org's configuration.

A.3

Enforced and mapped, by clause family

Of the 121 SOC 2 controls in the documented catalog that cite a clause, modules enforce 80. A control appears once under each clause family it maps to.

CC632 of 53
CC725 of 32
A119 of 27
PI118 of 25
C15 of 6
CC82 of 3
P41 of 2
CC41 of 1
CC11 of 1

The catalog maps 19 more controls to SOC 2 without naming a clause, 14 of them enforced. They are listed apart at the end of A.4 and left out of these counts.

Every row is a control your auditor can look up.

Filter the register, or search by control name or clause, for example CC6.1.

121 of 121 shown

Each control links to its public docs page.

Enforced
Modules set this control before anything is deployed.
Mapped
Documented on its docs page, not set by modules. Your team owns it.
A.4

Control register

ControlStatusSOC 2 clauses
ACM certificates should not use wildcard certificatesEnforcedCC6.1 (supporting)
AppSync API caches should have encryption in transit enabledEnforcedCC6.7
AppSync GraphQL APIs should have field-level logging enabledEnforcedA1.2
CloudFront distributions should require encryption in transitEnforcedCC6.7
CloudFront distributions should have field level encryption enabledEnforcedPI1.4
CloudFront distributions access logs should be enabledEnforcedA1.2, PI1.2
CloudFront distributions should use the recommended TLS security policyEnforcedCC6.7
CloudWatch alarms should have an action configuredEnforcedCC7.4
CloudWatch alarms should have action enabledEnforcedCC4.2
CloudWatch log groups should have retention period of at least 365 daysEnforcedC1.2, CC7.2, CC7.3, P4.2 (supporting)
DMS replication instances should specify a KMS key for storage encryptionEnforcedCC6.1 (supporting)
DMS replication instances should not be publicly accessibleEnforcedCC6.6
DynamoDB tables should have AWS KMS encryption enabledEnforcedPI1.5
DynamoDB tables should have encryption enabledEnforcedPI1.5
DynamoDB tables should have point-in-time recovery enabledEnforcedA1.2, CC7.4
Attached EBS volumes should have encryption enabledEnforcedCC6.1, PI1.5
Classic Load Balancers should have connection draining enabledEnforcedCC8.1 (supporting)
EC2 instances should have detailed monitoring enabledEnforcedCC7.2
EC2 instances should have EBS optimization enabledEnforcedA1.2
EC2 instances should be in a VPCEnforcedCC6.6
EC2 instances should not have a public IP addressEnforcedCC6.6
EC2 instances should have termination protection enabledEnforcedA1.2 (supporting)
EC2 instances should use IMDSv2EnforcedCC7.2
EC2 launch templates should use Instance Metadata Service Version 2 (IMDSv2)EnforcedCC6.1 (supporting)
EC2 launch templates should not assign public IPs to network interfacesEnforcedCC6.6
ECR repositories should have image scan on push enabledEnforcedCC7.1
ECS services should not have public IP addresses assigned automaticallyEnforcedCC6.6
EFS file systems should have encryption at rest enabledEnforcedCC6.1
ElastiCache Redis clusters should have automatic backups enabled with a retention period of 15 days or greaterEnforcedA1.2
ElastiCache for Redis replication groups should be encrypted in transitEnforcedCC6.7
ElastiCache for Redis replication groups before version 6.0 should use Redis AuthEnforcedCC6.1 (supporting)
ELB application and classic load balancer logging should be enabledEnforcedA1.2, CC7.2, CC7.3, PI1.2
ELB application load balancers should drop invalid HTTP headersEnforcedCC6.7
EMR cluster Kerberos should be enabledEnforcedCC6.3
FSx for NetApp ONTAP file systems should be configured for Multi-AZ deploymentEnforcedA1.2
FSx for OpenZFS file systems should be configured for Multi-AZ deploymentEnforcedA1.2
API Gateway V2 stages should have access logging configuredEnforcedA1.2, PI1.2
KMS CMK rotation should be enabledEnforcedPI1.5
Lambda functions should have concurrent execution limit configuredEnforcedCC7.2
Lambda functions should be configured with a dead-letter queueEnforcedCC7.4
Lambda functions should encrypt environment variables with a specified KMS keyEnforcedCC6.1 (supporting)
Lambda functions should be in a VPCEnforcedCC6.6
Log groups should have encryption at rest enabledEnforcedCC7.3, PI1.4
MSK clusters should require TLS for client-broker connectionsEnforcedCC6.7
Network Firewall firewalls should have subnet change protection enabledEnforcedCC8.1 (supporting)
OpenSearch domains should have audit logging enabledEnforcedA1.2, CC7.3
OpenSearch domains should have logging to CloudWatch Logs enabledEnforcedA1.2, CC7.3
Aurora PostgreSQL DB clusters should publish logs to CloudWatch LogsEnforcedCC7.2 (supporting)
RDS DB clusters should be encrypted at restEnforcedPI1.5
RDS Aurora cluster parameter groups should require TLS for client connectionsEnforcedCC6.7 (supporting)
RDS DB instance backup should be enabledEnforcedA1.2, CC7.4
RDS DB instances should be integrated with CloudWatch logsEnforcedA1.2, CC7.2, CC7.3, PI1.3
RDS DB instances should be configured to copy tags to snapshotsEnforcedCC7.5
RDS DB instances should have deletion protection enabledEnforcedC1.1
RDS DB instance encryption at rest should be enabledEnforcedCC6.1, PI1.5
RDS DB instances should have iam authentication enabledEnforcedCC1.3
RDS for MariaDB DB instances should publish logs to CloudWatch LogsEnforcedCC7.2
RDS for PostgreSQL DB instances should publish logs to CloudWatch LogsEnforcedCC7.2
RDS for SQL Server DB instances should publish logs to CloudWatch LogsEnforcedCC7.2
Redshift clusters should have audit logging enabledEnforcedCC7.2, CC7.3
Redshift cluster encryption in transit should be enabledEnforcedCC6.7
Redshift clusters should prohibit public accessEnforcedCC6.6
S3 buckets should have cross-region replication enabledEnforcedA1.2
S3 buckets should have default encryption enabledEnforcedCC6.1, PI1.4
S3 buckets should have event notifications enabledEnforcedCC7.3
S3 buckets should have logging enabledEnforcedA1.2, CC7.2, CC7.3
S3 buckets should not be accessible to all authenticated usersEnforcedCC6.1
S3 buckets should have object lock enabledEnforcedC1.1, PI1.5
S3 buckets should prohibit public read accessEnforcedCC6.1, CC6.6
S3 buckets should prohibit public write accessEnforcedCC6.1, CC6.6
S3 buckets should have static website hosting disabledEnforcedCC6.6 (supporting)
S3 buckets with versioning enabled should have lifecycle policies configuredEnforcedC1.1
S3 buckets should have versioning enabledEnforcedA1.2, C1.2, CC7.4, PI1.5
S3 public access should be blocked at account levelEnforcedCC6.6
Step Functions state machines should have logging enabledEnforcedA1.2, PI1.3
SNS topics should be encrypted at restEnforcedCC6.1, PI1.4
SQS queues should have a dead-letter queue configuredEnforcedPI1.3 (supporting)
VPC subnet auto assign public IP should be disabledEnforcedCC6.6
EC2 VPN connections should have logging enabledEnforcedCC7.2
WAFv2 rules should have CloudWatch metrics enabledEnforcedA1.2, CC7.2
API Gateway methods should require an authorizerMappedCC6.1 (supporting)
API Gateway methods should validate request parametersMappedPI1.2 (supporting)
API Gateway V2 routes should require an authorizerMappedCC6.1 (supporting)
API Gateway stages should have cache encryption at rest enabledMappedCC6.7
API Gateway stages should have logging enabledMappedA1.2, CC7.2, CC7.3, PI1.2
Athena workgroups should have logging enabledMappedA1.2
Backup plan rules should retain recovery points for at least 35 daysMappedP4.2 (supporting)
CloudFormation stacks should have rollback enabledMappedCC8.1 (supporting)
CloudTrail trails should be integrated with CloudWatch logsMappedA1.2, CC7.2, CC7.3, PI1.3
CloudTrail trails should have logs encrypted using a customer managed KMS keyMappedCC6.1
CloudTrail trails should have log file validation enabledMappedCC7.3, PI1.3
CodeBuild projects should specify a KMS key for build output encryptionMappedCC6.1 (supporting)
CodeBuild projects should have logging enabledMappedA1.2
DynamoDB Accelerator clusters should be encrypted in transitMappedCC6.7
DMS endpoints for Redis OSS should have TLS enabledMappedCC6.7
DocumentDB clusters should have deletion protection enabledMappedA1.2 (supporting)
EBS snapshots should be encryptedMappedCC7.5
EC2 Client VPN endpoints should have client connection logging enabledMappedA1.2
EC2 transit gateways should have auto accept shared attachments disabledMappedCC6.7
Elasticsearch domains should have audit logging enabledMappedA1.2
ES domain encryption at rest should be enabledMappedCC6.1
ES domains should be in a VPCMappedCC6.6
Elasticsearch domain node-to-node encryption should be enabledMappedCC6.7
Glue jobs CloudWatch logs encryption should be enabledMappedPI1.4
Glue jobs S3 encryption should be enabledMappedPI1.4
IAM password policies should have strong configurationsMappedCC6.2
Kinesis streams should have an adequate data retention periodMappedC1.2
Kinesis streams should have server side encryption enabledMappedPI1.4
MQ brokers should have audit log streaming to CloudWatch enabledMappedA1.2
MQ brokers should restrict public accessMappedCC6.6
MSK Connect connectors should be encrypted in transitMappedCC6.7
MSK connectors should have logging enabledMappedCC7.2
Neptune DB clusters should be configured to copy tags to snapshotsMappedCC7.5
Redshift Serverless namespaces should export logs to CloudWatch LogsMappedCC7.2
Redshift Serverless workgroups should have enhanced VPC routing enabledMappedCC6.7 (supporting)
Redshift Serverless workgroups should prohibit public accessMappedCC6.6
SageMaker endpoint configuration encryption should be enabledMappedCC6.1
SageMaker notebook instances should not have direct internet accessMappedCC6.6
SageMaker notebook instance encryption should be enabledMappedCC6.1
EC2 VPC Block Public Access settings should block internet gateway trafficMappedCC6.6
VPC endpoint services should have acceptance required enabledMappedCC6.6 (supporting)

Supporting: the control is partial or indirect evidence for the clause, not full enforcement.

Clause IDs for the auditor. Your stack stays as it is.

Compliance.tf works alongside your scanners, plan policy, CSPM and GRC tool. It sets the controls in the modules and lists the clause each one is there for.

A.5

Evidence

A.5.1

What compliance.tf gives your auditor

  • The SOC 2 clause IDs behind each enforced setting, with stable control IDs and public docs pages.
  • The config snapshot bound to each environment, and the per-action audit log of promotions between environments.
A.5.2

What comes from your AWS account and GRC tool

Evidence of what actually runs comes from your own account, for example AWS Config and your CSPM. Your GRC tool keeps tracking policies and audit workflows.

A.6

Plans for SOC 2

SOC 2 is in the 30-day trial and in Full Access, $1,000 a year on AWS Marketplace. Schedule of fees.

A.7

Questions about SOC 2

A.7.1

Which Trust Services Criteria does this cover?

Compliance.tf enforces infrastructure controls mapped to Trust Services Criteria, for example CC6 (Logical and Physical Access Controls), CC7 (System Operations) and CC8 (Change Management). These are the criteria tied to AWS resource configuration: encryption at rest and in transit, access blocking, logging, versioning, and lifecycle policies. The control register lists every criteria family with the controls modules enforce and the ones left to you.

A.7.2

Can I adopt this gradually, or is it all-or-nothing?

Fully incremental. Start with one module in one environment. Your existing modules continue working untouched. If you use Terragrunt or Terramate to orchestrate your runs, nothing changes - you're only swapping the module source line. There is no global policy agent to deploy, no wrapper binary, no sidecar. Each module source line is independent.

A.7.3

What if we want to switch back?

Each module keeps the inputs and outputs of its terraform-aws-modules counterpart and needs no state migration, so switching back is the same source line change in reverse.