NIST 800-53 controls built into your Terraform modules. Enforced before apply.
Access control, audit logging, system protection and configuration management on AWS resources. The modules enforce these controls before apply and list the NIST SP 800-53 Rev 5 control ID each one maps to, where the catalog names one.
Modules enforce 77 of 96 NIST 800-53 controls in the catalog. Of the 62 that cite a NIST 800-53 clause, they enforce 49. The controls they do not enforce stay with your team, with risk assessment, security plans, training 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 F: NIST 800-53
- Framework
- NIST SP 800-53 Rev 5
- For
- Your team, on Terraform
Scope for NIST 800-53
Federal agencies and their contractors use NIST 800-53 as the security baseline. If you sell to the US government or plan for FedRAMP, it is where you start.
Covers
- Infrastructure controls on AWS resources that map to NIST SP 800-53 Rev 5 control IDs, by control family in F.3.
- terraform-aws-modules through the NIST 800-53 framework host or your org endpoint, and resources written by hand outside modules once your team switches to the compliance.tf provider.
Stays with your team
- Risk assessment documentation (RA family).
- Security planning and system security plans (PL family).
- Contingency planning procedures beyond backup configuration (CP family).
- Personnel security and screening (PS family).
- Awareness and training (AT family).
- Incident response procedures (IR family).
- Physical and environmental protection (PE family).
- Resources outside compliance.tf module coverage, and every control F.4 lists as Mapped: 13 with a NIST 800-53 clause and 6 without one.
The source line
Point a module at the NIST 800-53 framework host. Same inputs and outputs, no state migration. Terraform 1.0 or later.
- source = "terraform-aws-modules/s3-bucket/aws" + source = "nist80053.compliance.tf/terraform-aws-modules/s3-bucket/aws" version = "~> 5.0"
With an org endpoint, the source names your org host instead, and NIST 800-53comes from your org's configuration.
Enforced and mapped, by control family
Of the 62 NIST 800-53 controls in the documented catalog that cite a clause, modules enforce 49. A control appears once under each control family it maps to.
The catalog maps 34 more controls to NIST 800-53 without naming a clause, 28 of them enforced. They are listed apart at the end of F.4 and left out of these counts.
Every row is a control your assessor can look up.
Filter the register, or search by control name or clause, for example SC-28.
62 of 62 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.
Control register
| Control | Status | NIST 800-53 clauses |
|---|---|---|
| CloudWatch alarms should have an action configured | Enforced | AC-2(12), IA-10 |
| CloudWatch log groups should have retention period of at least 365 days | Enforced | AC-16(b), AU-6(3), AU-6(4), AU-6(6), AU-6(9), AU-11(1), AU-12(1), AU-12(2), AU-12(3), AU-14(a), AU-14(b), AU-11, CA-7(b), PM-31, SI-12, AU-10, PM-14(a)(1), PM-14(b), PM-21(b), SC-28(2), SI-4(17) |
| DMS replication instances should not be publicly accessible | Enforced | SC-25 |
| DynamoDB tables should have AWS KMS encryption enabled | Enforced | AU-9(3), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| DynamoDB tables should have encryption enabled | Enforced | AU-9(3), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| DynamoDB tables should have point-in-time recovery enabled | Enforced | CP-1(2), CP-2(5), CP-6(2), CP-9(a), CP-9(b), CP-9(c), CP-10(2), SC-5(2), SI-13(5), CP-10 |
| Attached EBS volumes should have encryption enabled | Enforced | AU-9(3), CM-6(a), CM-9(b), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| EC2 instances should have IAM profile attached | Enforced | AC-3, CM-5(1)(a), CM-6(a), IA-3(4), IA-9 |
| EC2 instances should be in a VPC | Enforced | SC-25 |
| EC2 instances should not have a public IP address | Enforced | AC-2(6), AC-3(7), AC-4(21), AC-6, AC-17(1), AC-17(4)(a), AC-17(9), AC-17(10), AC-17(b), AC-3, MP-2, SC-7(2), SC-7(3), SC-7(7), SC-7(9)(a), SC-7(11), SC-7(12), SC-7(16), SC-7(20), SC-7(21), SC-7(24)(b), SC-7(25), SC-7(26), SC-7(27), SC-7(28), SC-7(a), SC-7(b), SC-7(c), SC-25 |
| EC2 instances should use IMDSv2 | Enforced | AC-2(6), AC-3(3), AC-3(3)(a), AC-3(3)(b)(1), AC-3(3)(c), AC-3(4), AC-3(4)(a), AC-3(4)(b), AC-3(4)(c), AC-3(4)(d), AC-3(4)(e), AC-3(7), AC-3(8), AC-3(12)(a), AC-3(13), AC-3(15)(a), AC-3(15)(b), AC-4(28), AC-6, AC-24, AC-3, CM-5(1)(a), MP-2, SA-8(20), SC-23(3) |
| ECR repositories should have image scan on push enabled | Enforced | SI-2(2), SI-2(5) |
| EFS file systems should have encryption at rest enabled | Enforced | AU-9(3), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| ELB application and classic load balancer logging should be enabled | Enforced | AC-4(26), AU-2(b), AU-3(a), AU-3(b), AU-3(c), AU-3(d), AU-3(e), AU-3(f), AU-6(3), AU-6(4), AU-6(6), AU-6(9), AU-8(b), AU-12(1), AU-12(2), AU-12(3), AU-12(4), AU-12(a), AU-12(c), AU-14(3), AU-14(a), AU-14(b), CA-7(b), CM-5(1)(b), PM-31, IA-3(3)(b), MA-4(1)(a), AU-10, PM-14(a)(1), PM-14(b), SC-7(9)(b), SI-4(17), SI-7(8) |
| ELB application load balancer deletion protection should be enabled | Enforced | SC-22, CA-7(4)(c), CM-2(2), CM-2(a), CM-3(a), CM-8(6), CP-1(a)(1)(b), CP-2(5), CP-2(a), CP-2(d), CP-2(e), SA-15(a)(4), SC-5(2) |
| ELB network load balancers should have TLS listener security policy configured | Enforced | SC-8(1) |
| ELB listeners should use approved SSL/TLS protocol versions | Enforced | SC-8(1), SC-23(5) |
| KMS CMK rotation should be enabled | Enforced | CM-6(a), CM-9(b), SC-12, SA-9(6), SC-12(2), SC-12(6) |
| Lambda functions should have concurrent execution limit configured | Enforced | SC-6 |
| Lambda functions should be in a VPC | Enforced | SC-25 |
| Lambda functions should restrict public URL | Enforced | AC-2(6), AC-3(7), AC-4(21), AC-6, AC-17(1), AC-17(4)(a), AC-17(9), AC-17(10), AC-17(b), AC-3, MP-2, SC-7(2), SC-7(3), SC-7(7), SC-7(9)(a), SC-7(11), SC-7(12), SC-7(16), SC-7(20), SC-7(21), SC-7(24)(b), SC-7(25), SC-7(26), SC-7(27), SC-7(28), SC-7(a), SC-7(b), SC-7(c), SC-25 |
| Log groups should have encryption at rest enabled | Enforced | AU-9(3), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| OpenSearch domains should have encryption at rest enabled | Enforced | AU-9(3), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| OpenSearch domains should have logging to CloudWatch Logs enabled | Enforced | AU-10 |
| OpenSearch domains node-to-node encryption should be enabled | Enforced | AC-4(22), AC-24(1), AU-9(3), CA-9(b), AC-4, PM-17(b), SC-7(4)(b), SC-7(4)(g), SC-8(1), SC-8(2), SC-8(3), SC-8(4), SC-8(5), SC-13(a), SC-23, SI-1(a)(2), SC-8 |
| RDS DB instances and clusters should have enhanced monitoring enabled | Enforced | AU-12(3), AU-14(a), AU-14(b), CA-2(2), CA-7(b), CA-7, PM-31, PM-14(a)(1), PM-14(b), SC-36(1)(a), SI-2(a) |
| RDS DB instance backup should be enabled | Enforced | CP-1(2), CP-2(5), CP-6(1), CP-6(2), CP-6(a), CP-9(a), CP-9(b), CP-9(c), CP-10(2), SC-5(2), SI-13(5), CP-10 |
| RDS DB instances should be integrated with CloudWatch logs | Enforced | AC-2(4), AC-3(1), AC-3(10), AC-4(26), AC-6(9), AU-2(b), AU-3(a), AU-3(b), AU-3(c), AU-3(d), AU-3(e), AU-3(f), AU-6(3), AU-6(4), AU-6(6), AU-6(9), AU-8(b), AU-12(1), AU-12(2), AU-12(3), AU-12(4), AU-12(a), AU-12(c), AU-14(3), AU-14(a), AU-14(b), CA-7(b), CM-5(1)(b), PM-31, IA-3(3)(b), MA-4(1)(a), AU-10, PM-14(a)(1), PM-14(b), SC-7(9)(b), SI-1(1)(c), SI-3(8)(b), SI-4(2), SI-4(17), SI-4(20), SI-7(8), SI-10(1)(c) |
| RDS DB instances should have deletion protection enabled | Enforced | SC-22, CA-7(4)(c), CM-3(a), CP-1(a)(1)(b), CP-2(5), CP-2(a), CP-2(d), CP-2(e), SA-15(a)(4), SC-5(2), SI-13(5) |
| RDS DB instance encryption at rest should be enabled | Enforced | AU-9(3), CP-9(8), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| RDS DB instances should have multiple AZ enabled | Enforced | SC-22, CP-1(a)(1)(b), CP-2(5), CP-2(6), CP-2(a), CP-2(d), CP-2(e), CP-6(2), SC-36, SC-6, SC-5(2), SI-13(5), CP-10 |
| RDS DB instances should prohibit public access | Enforced | SC-25 |
| Redshift clusters should have audit logging enabled | Enforced | AC-2(4), AC-3(1), AC-3(10), AC-4(26), AC-6(9), AU-2(b), AU-3(a), AU-3(b), AU-3(c), AU-3(d), AU-3(e), AU-3(f), AU-6(3), AU-6(4), AU-6(6), AU-6(9), AU-8(b), AU-9(3), AU-12(1), AU-12(2), AU-12(3), AU-12(4), AU-12(a), AU-12(c), AU-14(3), AU-14(a), AU-14(b), CA-7(b), CM-5(1)(b), PM-31, CP-9(d), IA-3(3)(b), MA-4(1)(a), AU-10, PM-14(a)(1), PM-14(b), SC-7(9)(b), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-1(1)(c), SI-3(8)(b), SI-4(2), SI-4(17), SI-4(20), SI-7(8), SI-10(1)(c), SI-19(4) |
| Redshift clusters should have automatic upgrades to major versions enabled | Enforced | CM-2(b), CM-3(3), CP-9(a), CP-9(b), CP-9(c), SC-5(2), SI-2(2), SI-2(5), SI-2(c), SI-2(d) |
| Redshift clusters should prohibit public access | Enforced | SC-25 |
| S3 buckets should have default encryption enabled | Enforced | AU-9(3), SC-28(1) |
| S3 buckets should have default encryption enabled using KMS | Enforced | AU-9(3), SC-28(1) |
| S3 buckets should have logging enabled | Enforced | AC-2(4), AC-3(1), AC-3(10), AC-4(26), AC-6(9), AU-2(b), AU-3(a), AU-3(b), AU-3(c), AU-3(d), AU-3(e), AU-3(f), AU-6(3), AU-6(4), AU-6(6), AU-6(9), AU-8(b), AU-12(1), AU-12(2), AU-12(3), AU-12(4), AU-12(a), AU-12(c), AU-14(3), AU-14(a), AU-14(b), CA-7(b), CM-5(1)(b), CM-6(a), CM-9(b), PM-31, IA-3(3)(b), MA-4(1)(a), AU-10, PM-14(a)(1), PM-14(b), SC-7(9)(b), SI-1(1)(c), SI-3(8)(b), SI-4(2), SI-4(17), SI-4(20), SI-7(8), SI-10(1)(c) |
| S3 buckets should not be accessible to all authenticated users | Enforced | AC-2(6), AC-3(7), AC-4(21), AC-6, AC-17(1), AC-17(4)(a), AC-17(9), AC-17(10), AC-17(b), AC-3, CM-6(a), CM-9(b), MP-2, SC-7(2), SC-7(3), SC-7(7), SC-7(9)(a), SC-7(11), SC-7(12), SC-7(16), SC-7(20), SC-7(21), SC-7(24)(b), SC-7(25), SC-7(26), SC-7(27), SC-7(28), SC-7(a), SC-7(b), SC-7(c), SC-25 |
| S3 buckets should prohibit public read access | Enforced | AC-2(6), AC-3(7), AC-4(21), AC-6, AC-17(1), AC-17(4)(a), AC-17(9), AC-17(10), AC-17(b), AC-3, CM-6(a), CM-9(b), MP-2, SC-7(2), SC-7(3), SC-7(7), SC-7(9)(a), SC-7(11), SC-7(12), SC-7(16), SC-7(20), SC-7(21), SC-7(24)(b), SC-7(25), SC-7(26), SC-7(27), SC-7(28), SC-7(a), SC-7(b), SC-7(c), SC-25 |
| S3 buckets should prohibit public write access | Enforced | AC-2(6), AC-3(4), AC-3(7), AC-4(21), AC-6, AC-17(1), AC-17(4)(a), AC-17(9), AC-17(10), AC-17(b), AC-3, CM-6(a), CM-9(b), MP-2, SC-7(2), SC-7(3), SC-7(7), SC-7(9)(a), SC-7(11), SC-7(12), SC-7(16), SC-7(20), SC-7(21), SC-7(24)(b), SC-7(25), SC-7(26), SC-7(27), SC-7(28), SC-7(a), SC-7(b), SC-7(c), SC-25 |
| S3 buckets with versioning enabled should have lifecycle policies configured | Enforced | AU-11, SI-14(2) |
| S3 buckets should have versioning enabled | Enforced | AU-9(2), CP-1(2), CP-2(5), CP-6(1), CP-6(2), CP-6(a), CP-9(a), CP-9(b), CP-9(c), CP-10(2), PM-11(b), PM-17(b), SC-5(2), SC-16(1), SI-1(a)(2), SI-13(5), CP-10 |
| S3 public access should be blocked at account level | Enforced | SC-25 |
| S3 public access should be blocked at bucket level | Enforced | AU-9(2), SC-25 |
| SNS topics should be encrypted at rest | Enforced | AU-9(3), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1) |
| VPC Security groups should only allow unrestricted incoming traffic for authorized ports | Enforced | SC-7, SC-7(13) |
| VPC security groups should restrict ingress from 0.0.0.0/0 or ::/0 to cassandra ports 7199 or 9160 or 8888 | Enforced | SC-7(13) |
| VPC subnet auto assign public IP should be disabled | Enforced | SC-25 |
| API Gateway REST API stages should have a client certificate configured | Mapped | AC-4(22), AC-17(2), AC-24(1), AU-9(3), CA-9(b), IA-5(1)(c), AC-4, PM-17(b), SC-7(4)(b), SC-7(4)(g), SC-7(5), SC-8(1), SC-8(2), SC-8(3), SC-8(4), SC-8(5), SC-13(a), SC-23, SI-1(a)(2), SC-8 |
| API Gateway stages should have logging enabled | Mapped | AC-4(26), AU-2(b), AU-3(a), AU-3(b), AU-3(c), AU-3(d), AU-3(e), AU-3(f), AU-6(3), AU-6(4), AU-6(6), AU-6(9), AU-8(b), AU-12(1), AU-12(2), AU-12(3), AU-12(4), AU-12(a), AU-12(c), AU-14(3), AU-14(a), AU-14(b), CA-7(b), CM-5(1)(b), PM-31, IA-3(3)(b), MA-4(1)(a), AU-10, PM-14(a)(1), PM-14(b), SC-7(9)(b), SI-4(17), SI-7(8) |
| CloudFormation stacks should have notifications enabled | Mapped | CM-8(3) |
| CloudTrail trails should be integrated with CloudWatch logs | Mapped | AC-2(4), AC-3(1), AC-3(10), AC-4(26), AC-6(9), AU-2(b), AU-3(a), AU-3(b), AU-3(c), AU-3(d), AU-3(e), AU-3(f), AU-4(1), AU-6(1), AU-6(3), AU-6(4), AU-6(5), AU-6(6), AU-6(9), AU-7(1), AU-8(b), AU-9(7), AU-12(1), AU-12(2), AU-12(3), AU-12(4), AU-12(a), AU-12(c), AU-14(3), AU-14(a), AU-14(b), CA-7(b), CM-5(1)(b), CM-6(a), CM-9(b), PM-31, AU-16, IA-3(3)(b), MA-4(1)(a), AU-10, PM-14(a)(1), PM-14(b), SC-7(9)(b), SI-1(1)(c), SI-3(8)(b), SI-4(2), SI-4(17), SI-4(20), SI-7(8), SI-10(1)(c) |
| CloudTrail trails should have logs encrypted using a customer managed KMS key | Mapped | AU-9(3), CM-6(a), CM-9(b), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| CloudTrail trails should have log file validation enabled | Mapped | AU-9(a), CM-6(a), CM-9(b), PM-11(b), PM-17(b), SA-1(1), SA-10(1), SC-16(1), SI-1(a)(2), SI-4(d), SI-7(1), SI-7(3), SI-7(7), SI-7(a) |
| ES domain encryption at rest should be enabled | Mapped | AU-9(3), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
| ES domains should be in a VPC | Mapped | SC-25 |
| Elasticsearch domain should send logs to CloudWatch | Mapped | AU-10 |
| Elasticsearch domain node-to-node encryption should be enabled | Mapped | AC-4(22), AC-24(1), AU-9(3), CA-9(b), AC-4, PM-17(b), SC-7(4)(b), SC-7(4)(g), SC-8(1), SC-8(2), SC-8(3), SC-8(4), SC-8(5), SC-13(a), SC-23, SI-1(a)(2), SC-8 |
| IAM password policies should have minimum length set to 14 or greater | Mapped | AC-2(1), AC-2(3), AC-2(3)(a), AC-2(3)(b), AC-2(3)(c), AC-2(3)(d), AC-2(d)(1), AC-3(3), AC-3(3)(a), AC-3(3)(b)(1), AC-3(3)(c), AC-3(4), AC-3(4)(a), AC-3(4)(b), AC-3(4)(c), AC-3(4)(d), AC-3(4)(e), AC-3(8), AC-3(12)(a), AC-3(13), AC-3(15)(a), AC-3(15)(b), AC-4(28), AC-7(4), AC-7(4)(a), AC-24, CM-5(1)(a), CM-6(a), CM-9(b), CM-12(b), IA-4(d), IA-5, IA-5(1)(f), IA-5(1)(g), IA-5(1)(h), IA-5(18)(a), IA-5(18)(b), IA-5(b), IA-5(c), IA-5(d), IA-5(f), IA-5(h), IA-8(2)(b), MA-4(c), SC-23(3) |
| SageMaker notebook instances should not have direct internet access | Mapped | AC-2(6), AC-3(7), AC-4(21), AC-6, AC-17(1), AC-17(4)(a), AC-17(9), AC-17(10), AC-17(b), AC-3, MP-2, SC-7(2), SC-7(3), SC-7(7), SC-7(9)(a), SC-7(11), SC-7(12), SC-7(16), SC-7(20), SC-7(21), SC-7(24)(b), SC-7(25), SC-7(26), SC-7(27), SC-7(28), SC-7(a), SC-7(b), SC-7(c), SC-25 |
| SageMaker notebook instance encryption should be enabled | Mapped | AU-9(3), CP-9(d), SC-8(3), SC-8(4), SC-13(a), SC-28(1), SI-19(4) |
Enforced or mapped without a named NIST 800-53 clause
The catalog lists these 34 controls under NIST 800-53 but names no NIST 800-53 clause for them, so the register and the counts in F.3 leave them out. Each still links to its docs page.
Clause IDs for the assessor. 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.
Evidence
What compliance.tf gives your assessor
- The NIST 800-53 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.
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.
Related reading
Make Non-Compliant Terraform Impossible, Why Enterprises Choose Compliance.tf, the comparisons with other tools, and the NIST 800-53 framework registry at nist80053.compliance.tf.
Plans for NIST 800-53
NIST 800-53 is in the 30-day trial and in Full Access, $1,000 a year on AWS Marketplace. Schedule of fees.
Questions about NIST 800-53
Is this Rev 4 or Rev 5?
Compliance.tf maps controls to NIST 800-53 Revision 5, the current version published in September 2020. Rev 5 added privacy controls and reorganized several control families. If you need Rev 4 mappings for legacy authorization packages, contact us.
Which control families does this cover?
Compliance.tf enforces controls from the families tied to infrastructure configuration, for example Access Control (AC), Audit and Accountability (AU), System and Communications Protection (SC), Contingency Planning (CP), System and Information Integrity (SI), Configuration Management (CM), Identification and Authentication (IA), Assessment, Authorization, and Monitoring (CA), and System and Services Acquisition (SA). The control register lists every family with its controls.
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.
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.