RDS DB instances should be integrated with CloudWatch logs
Database logs left on the instance are ephemeral. RDS storage can rotate or lose logs during failovers, restarts, or storage pressure events. Streaming logs to CloudWatch Logs makes them durable, searchable, and available for metric filters and alarms without SSH or RDS API polling.
CloudWatch integration also unlocks cross-service correlation. When an application error in Lambda or ECS coincides with a slow query or authentication failure in RDS, having both log streams in the same destination cuts mean-time-to-diagnosis significantly.
Retrofit consideration
audit log requires enabling the MariaDB audit plugin settings (for example, server_audit_logging=1) in a custom parameter group, which may require a reboot depending on parameter apply type.Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
This control is enforced automatically with Compliance.tf modules. Start free trial
If you use terraform-aws-modules/rds/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = ">=7.0.0"
allocated_storage = 20
db_name = "myapp"
db_subnet_group_name = "example-db-subnet-group"
engine = "mysql"
engine_version = "8.0.41"
family = "mysql8.0"
identifier = "abc123"
instance_class = "db.t3.micro"
major_engine_version = "8.0"
password_wo = "change-me-in-production"
skip_final_snapshot = true
username = "dbadmin"
vpc_security_group_ids = ["sg-12345678"]
}Use AWS provider resources directly. See docs for the resources involved: aws_db_instance.
resource "aws_db_instance" "this" {
allocated_storage = 20
enabled_cloudwatch_logs_exports = ["general", "slowquery"]
engine = "mysql"
identifier = "pofix-abc123"
instance_class = "db.t3.micro"
monitoring_interval = 60
monitoring_role_arn = "arn:aws:iam::123456789012:role/example-role"
password = "ChangeMe123!"
skip_final_snapshot = true
username = "dbadmin"
}What this control checks
In the aws_db_instance resource, enabled_cloudwatch_logs_exports must be a non-empty list of log type strings appropriate for the database engine. For MySQL and MariaDB, valid values include "audit", "error", "general", and "slowquery". For PostgreSQL, valid values are "postgresql" and "upgrade". For Oracle, use "alert", "audit", "listener", and "trace". For SQL Server, use "agent" and "error". A configuration that omits enabled_cloudwatch_logs_exports entirely or sets it to [] fails this control. RDS handles log delivery to CloudWatch Logs automatically once export is configured.
Common pitfalls
Engine-specific log types cause silent no-ops
Specifying a log type that doesn't match the engine (for example, "slowquery" on a PostgreSQL instance) produces a Terraform apply error, which is at least visible. The subtler problem: specifying "audit" on MySQL without setting server_audit_logging = 1 in the DB parameter group creates an empty CloudWatch log group. The control passes, but nothing is actually being logged.
Aurora instances use a different resource
This control targets aws_db_instance. Aurora clusters configure log exports on aws_rds_cluster using the same enabled_cloudwatch_logs_exports argument. If your fleet includes both Aurora and non-Aurora databases, you need to address both resource types separately.
CloudWatch Logs retention defaults to never expire
Log groups under /aws/rds/instance/ default to indefinite retention. Storage costs grow unbounded unless you set a retention policy via aws_cloudwatch_log_group with retention_in_days. Terraform can import or pre-create these log groups to manage retention before RDS creates them.
Read replicas need independent configuration
enabled_cloudwatch_logs_exports on a read replica aws_db_instance does not inherit from the source instance. Each replica must declare its own log exports explicitly.
Audit evidence
Auditors expect compliance evaluation results (from Config custom rules or conformance packs) showing all RDS DB instances as compliant. On the RDS instance Configuration tab, one or more log types should appear under "Published logs" pointing to CloudWatch Logs. The CloudWatch Logs console should contain log groups under the /aws/rds/instance/<instance-id>/<log-type> naming convention with recent log streams, confirming active delivery.
For deeper validation, CloudTrail ModifyDBInstance events should show EnableCloudwatchLogsExports in the request parameters, and Logs Insights queries against the exported log groups should return recent entries matching the expected engine log format.
Framework-specific interpretation
SOC 2: CC7.2 and CC7.3 ask for continuous monitoring of system components to detect anomalies and support incident response. Centralizing RDS logs in CloudWatch gives you the ongoing visibility into database behavior those criteria expect.
PCI DSS v4.0: Requirement 10.2 mandates audit logs capturing relevant events on CDE system components. For RDS instances processing cardholder data, CloudWatch log exports are how you meet that requirement and produce the centralized log collection that Requirement 10.5 expects examiners to verify.
HIPAA Omnibus Rule 2013: 45 CFR 164.312(b) requires audit controls that record and examine activity in systems containing ePHI. For RDS instances holding health data, CloudWatch log exports provide the database-level audit trail the rule calls for, covering access events and error conditions.
ISO/IEC 27001:2022: A.8.15 (Logging) and A.8.16 (Monitoring activities) expect operational logging and active monitoring of security events. Exporting RDS logs to CloudWatch covers both controls for the database layer.
GDPR: Articles 5(1)(f) and 32 require appropriate technical measures to maintain integrity, confidentiality, and the ability to detect and investigate unauthorized access to personal data. CloudWatch log exports support accountability by keeping auditable records of database activity in a durable, centralized location outside the instance.
NIS2 Directive (EU 2022/2555): Article 21 calls for incident handling and monitoring measures proportionate to organizational risk. Streaming RDS logs to CloudWatch supports that objective by making database security events detectable and analyzable, though it's one input into the broader risk management posture NIS2 expects.
NIST SP 800-53 Rev 5: AU-2, AU-3, AU-6, and SI-4 together require that events are defined, recorded with sufficient content, reviewed, and fed into active monitoring. CloudWatch integration puts RDS audit records in a place where metric filters and Logs Insights queries can satisfy all four controls for the database tier.
FedRAMP Moderate Baseline Rev 4: AU-2 and AU-12 require automated log generation and centralized collection from information system components. AU-6 adds review and analysis on top of that. Exporting RDS logs to CloudWatch is how you cover all three for the database layer at the Moderate baseline.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
- Compliance.tf Control:
rds_db_instance_cloudwatch_logs_enabled - AWS Config Managed Rules:
RDS_LOGGING_ENABLED,RDS_POSTGRESQL_LOGS_TO_CLOUDWATCH,RDS_SQL_SERVER_LOGS_TO_CLOUDWATCH - Checkov Check:
CKV_AWS_129 - Powerpipe Control:
aws_compliance.control.rds_db_instance_cloudwatch_logs_enabled - Prowler Check:
rds_instance_integration_cloudwatch_logs - AWS Security Hub Controls:
RDS.40,RDS.42,RDS.9
Last reviewed: 2026-03-09