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 = falsefor 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_immediatelyand does not cause DB downtime, but clients using the public path can lose connectivity. Verify an alternative path first, and reviewterraform planfor 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
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
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
- CWE-668
- AWS DB Instance publicly_accessible reference
- Reviewed Terraform AWS provider RDS implementation
- RDS module v3.0.0 inputs
- Terraform type conversion
- RDS connections and addressing in a VPC
- Changing RDS public-access settings
- DB instance argument changes in AWS provider 5.0
- RDS secret management
- Managing sensitive data in Terraform