RDS public-access configuration needs review

Check whether RDS needs public addressing, and prepare required private connections before disabling unnecessary public access.

Description

RDS publicly_accessible controls whether an instance uses public addressing. When public access is enabled and subnet routing and security groups permit external connections, internet clients can attempt database connections. Data access still requires database authentication and permissions.

Databases used only through internal connections should avoid public addressing and allow only required application and administration paths.

Potential impact

  • External clients that do not need access can gain a path for attempting database connections.
  • Leaked credentials or excessive permissions can increase the risk of unauthorized data reads or changes. A public address alone does not allow unauthenticated data access.

Remediation

  • Explicitly set publicly_accessible = false for internal instances. If using a module, verify that its input is reflected in the actual instance configuration.
  • Use subnets without a direct internet route, and allow only required clients through security groups and network ACLs. Prepare private connectivity such as VPN or Direct Connect for external private networks, and test DNS and authentication.
  • A public-access change applies immediately regardless of apply_immediately and does not cause DB downtime, but clients using the public path can lose connectivity. Verify an alternative path first, and review terraform plan for the effects of other changes applied together.

Examples

These partial examples change public access on the same resource. Define a supported db_instance_class, a DB subnet group in the same VPC, and the required security-group ID variables. Configure routing and access rules, and protect access to the RDS-managed password and Terraform state.

Before

hcl
resource "aws_db_instance" "public_instance" {
  allocated_storage    = 20
  storage_type         = "gp2"
  engine               = "mysql"
  instance_class       = var.db_instance_class
  db_name              = "mydb"
  username             = "foo"
  manage_master_user_password = true
  db_subnet_group_name  = var.db_subnet_group_name
  vpc_security_group_ids = var.db_security_group_ids
  publicly_accessible  = true
}

After

hcl
resource "aws_db_instance" "public_instance" {
  allocated_storage    = 20
  storage_type         = "gp2"
  engine               = "mysql"
  instance_class       = var.db_instance_class
  db_name              = "mydb"
  username             = "foo"
  manage_master_user_password = true
  db_subnet_group_name  = var.db_subnet_group_name
  vpc_security_group_ids = var.db_security_group_ids
  publicly_accessible  = false
}

Explanation:

  • Before: The instance is configured to use public addressing. External connections also require suitable routes and security-group permissions.
  • After: Public addressing is disabled. Verify that required clients connect through private paths with appropriate authentication and permissions.

References