RDS Instance CloudWatch Logs Integration
Overview
This check verifies that your Amazon RDS database instances are configured to export logs to CloudWatch Logs. When enabled, database logs (such as error logs, slow query logs, and general logs) are automatically sent to CloudWatch, where you can monitor, search, and set up alerts.
Risk
Without CloudWatch Logs integration:
- Security blind spots: You may miss signs of unauthorized access, SQL injection attempts, or credential misuse
- Slow incident response: Troubleshooting database issues becomes difficult without centralized, searchable logs
- Compliance gaps: Many compliance frameworks require centralized logging and monitoring of database activity
- Operational issues: Errors and slow queries may go unnoticed until they cause outages
Remediation Steps
Prerequisites
- AWS Console access with permissions to modify RDS instances
- The RDS instance must be running (not stopped)
Required IAM permissions
Your IAM user or role needs these permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:ModifyDBInstance",
"rds:DescribeDBInstances"
],
"Resource": "*"
}
]
}
AWS Console Method
- Open the Amazon RDS console
- In the left navigation, click Databases
- Select the database instance you want to modify
- Click the Modify button
- Scroll down to the Log exports section
- Check the boxes for the log types you want to export:
- Error log (recommended for all databases)
- General log (logs all SQL statements - can be verbose)
- Slow query log (logs queries exceeding a time threshold)
- Audit log (if using MySQL with the audit plugin)
- Scroll to the bottom and click Continue
- Choose when to apply changes:
- Apply immediately - changes take effect right away (may cause brief interruption)
- Apply during the next scheduled maintenance window - safer for production
- Click Modify DB instance
Available log types by database engine
| Engine | Available Log Types |
|---|---|
| MySQL | audit, error, general, slowquery |
| MariaDB | audit, error, general, slowquery |
| PostgreSQL | postgresql, upgrade |
| Oracle | alert, audit, listener, trace, oemagent |
| SQL Server | agent, error |
AWS CLI (optional)
Enable log exports for an existing RDS instance:
aws rds modify-db-instance \
--region us-east-1 \
--db-instance-identifier <your-db-instance-id> \
--cloudwatch-logs-export-configuration '{"EnableLogTypes":["error","general","slowquery"]}' \
--apply-immediately
Example for a MySQL instance named "my-database":
aws rds modify-db-instance \
--region us-east-1 \
--db-instance-identifier my-database \
--cloudwatch-logs-export-configuration '{"EnableLogTypes":["error","slowquery"]}' \
--apply-immediately
Example for a PostgreSQL instance:
aws rds modify-db-instance \
--region us-east-1 \
--db-instance-identifier my-postgres-db \
--cloudwatch-logs-export-configuration '{"EnableLogTypes":["postgresql","upgrade"]}' \
--apply-immediately
To disable specific log types (if needed):
aws rds modify-db-instance \
--region us-east-1 \
--db-instance-identifier my-database \
--cloudwatch-logs-export-configuration '{"DisableLogTypes":["general"]}' \
--apply-immediately
CloudFormation (optional)
Use the EnableCloudwatchLogsExports property on your AWS::RDS::DBInstance resource.
Example template:
AWSTemplateFormatVersion: '2010-09-09'
Description: RDS Instance with CloudWatch Logs Export enabled
Parameters:
DBInstanceIdentifier:
Type: String
Description: Identifier for the RDS instance
DBInstanceClass:
Type: String
Default: db.t3.micro
Description: Instance class for the RDS instance
Engine:
Type: String
Default: mysql
AllowedValues:
- mysql
- postgres
- mariadb
Description: Database engine type
MasterUsername:
Type: String
Description: Master username for the database
AllocatedStorage:
Type: Number
Default: 20
Description: Storage size in GB
Resources:
RDSInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: !Ref DBInstanceIdentifier
DBInstanceClass: !Ref DBInstanceClass
Engine: !Ref Engine
MasterUsername: !Ref MasterUsername
ManageMasterUserPassword: true
AllocatedStorage: !Ref AllocatedStorage
EnableCloudwatchLogsExports:
- error
- general
- slowquery
PubliclyAccessible: false
StorageEncrypted: true
DeletionProtection: true
Outputs:
DBInstanceId:
Description: RDS Instance Identifier
Value: !Ref RDSInstance
DBEndpoint:
Description: RDS Instance Endpoint
Value: !GetAtt RDSInstance.Endpoint.Address
To update an existing stack:
aws cloudformation update-stack \
--region us-east-1 \
--stack-name my-rds-stack \
--template-body file://template.yaml \
--parameters ParameterKey=DBInstanceIdentifier,ParameterValue=my-database \
ParameterKey=MasterUsername,ParameterValue=admin
Terraform (optional)
Use the enabled_cloudwatch_logs_exports argument on your aws_db_instance resource.
Example configuration:
variable "db_instance_identifier" {
description = "Identifier for the RDS instance"
type = string
}
variable "db_instance_class" {
description = "Instance class for the RDS instance"
type = string
default = "db.t3.micro"
}
variable "engine" {
description = "Database engine type"
type = string
default = "mysql"
}
variable "engine_version" {
description = "Database engine version"
type = string
default = "8.0"
}
variable "allocated_storage" {
description = "Storage size in GB"
type = number
default = 20
}
variable "db_username" {
description = "Master username for the database"
type = string
}
variable "db_password" {
description = "Master password for the database"
type = string
sensitive = true
}
# Log types vary by database engine:
# MySQL/MariaDB: audit, error, general, slowquery
# PostgreSQL: postgresql, upgrade
# Oracle: alert, audit, listener, trace
# SQL Server: agent, error
variable "enabled_cloudwatch_logs_exports" {
description = "List of log types to export to CloudWatch"
type = list(string)
default = ["error", "general", "slowquery"]
}
resource "aws_db_instance" "main" {
identifier = var.db_instance_identifier
instance_class = var.db_instance_class
engine = var.engine
engine_version = var.engine_version
allocated_storage = var.allocated_storage
storage_encrypted = true
username = var.db_username
password = var.db_password
# Enable CloudWatch Logs export
enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports
publicly_accessible = false
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "${var.db_instance_identifier}-final-snapshot"
tags = {
Name = var.db_instance_identifier
}
}
output "db_instance_id" {
description = "The RDS instance identifier"
value = aws_db_instance.main.id
}
output "db_instance_endpoint" {
description = "The connection endpoint for the RDS instance"
value = aws_db_instance.main.endpoint
}
output "cloudwatch_log_groups" {
description = "CloudWatch log groups created for this RDS instance"
value = [for log_type in var.enabled_cloudwatch_logs_exports : "/aws/rds/instance/${var.db_instance_identifier}/${log_type}"]
}
To apply changes to an existing instance, add the enabled_cloudwatch_logs_exports argument and run:
terraform plan
terraform apply
Verification
After enabling log exports, verify the configuration:
- Go to the RDS console and select your database
- In the Configuration tab, look for Log exports - it should list the enabled log types
- Go to CloudWatch Logs and look for log groups named
/aws/rds/instance/<your-db-instance-id>/<log-type>
CLI verification commands
Check which log exports are enabled:
aws rds describe-db-instances \
--region us-east-1 \
--db-instance-identifier <your-db-instance-id> \
--query 'DBInstances[0].EnabledCloudwatchLogsExports'
Expected output (example for MySQL):
[
"error",
"general",
"slowquery"
]
Verify CloudWatch log groups exist:
aws logs describe-log-groups \
--region us-east-1 \
--log-group-name-prefix /aws/rds/instance/<your-db-instance-id>
Additional Resources
- Publishing Database Logs to Amazon CloudWatch Logs
- Working with Amazon RDS Database Log Files
- Monitoring Amazon RDS
- CloudWatch Logs User Guide
Notes
- Log types vary by engine: Different database engines support different log types. Check the table above for your specific engine.
- Storage costs: CloudWatch Logs incurs storage costs. Consider setting up log retention policies to manage costs.
- Performance impact: Enabling the general log can impact database performance due to the volume of data logged. Use it sparingly in production.
- Parameter groups: Some log types (like slow query log) may require enabling additional settings in your DB parameter group. For MySQL, ensure
slow_query_log = 1and set an appropriatelong_query_timethreshold. - Apply timing: Changes may require a brief instance restart. Schedule changes during maintenance windows for production databases.