Description
Neither 0.0.0.0/0 nor ::/0 is a valid AWS subnet CIDR size. Allocate subnets with supported sizes within the VPC's address range. A subnet's address range is different from a route table's destination range.
Whether a subnet is public depends on routing, including a direct route to an internet gateway. Private addresses alone do not isolate a database; also review the RDS publicly_accessible setting and security groups.
Potential impact
- Invalid subnet CIDRs can prevent deployment.
- A public connection path combined with broad access rules can permit unnecessary database connection attempts. Data access still requires authentication and permissions.
Remediation
- Use valid, nonoverlapping subnet CIDRs within the VPC's address space. Check the DB subnet group's VPC and required Availability Zone arrangement.
- For internal-only connections, use subnets without a direct route to an internet gateway and set
publicly_accessibletofalse. Restrict routing, network ACLs, and security groups to required application and administration connections. - Changing an existing instance's subnet group can cause downtime. Review replacement and connection changes in
terraform plan, plan backups, recovery, and a maintenance window, then test actual client connections.
Examples
These partial examples compare subnet CIDRs. Define vpc_id, az_a and az_b in different Availability Zones, a supported db_instance_class, and a final snapshot name. The sample private ranges must belong to that VPC; configure routing and required security groups separately. Protect access to the RDS-managed password and Terraform state.
Before
resource "aws_db_instance" "public_subnet_example" {
allocated_storage = 20
engine = "mysql"
instance_class = var.db_instance_class
db_name = "mydb"
username = "foo"
manage_master_user_password = true
skip_final_snapshot = false
final_snapshot_identifier = var.final_snapshot_identifier
publicly_accessible = false
db_subnet_group_name = aws_db_subnet_group.subnetGroup.name
}
resource "aws_db_subnet_group" "subnetGroup" {
name = "main"
subnet_ids = [aws_subnet.frontend.id, aws_subnet.backend.id]
}
resource "aws_subnet" "frontend" {
availability_zone = var.az_a
vpc_id = var.vpc_id
cidr_block = "10.0.1.0/24"
}
resource "aws_subnet" "backend" {
availability_zone = var.az_b
vpc_id = var.vpc_id
cidr_block = "0.0.0.0/0"
}
After
resource "aws_db_instance" "public_subnet_example" {
allocated_storage = 20
engine = "mysql"
instance_class = var.db_instance_class
db_name = "mydb"
username = "foo"
manage_master_user_password = true
skip_final_snapshot = false
final_snapshot_identifier = var.final_snapshot_identifier
publicly_accessible = false
db_subnet_group_name = aws_db_subnet_group.subnetGroup.name
}
resource "aws_db_subnet_group" "subnetGroup" {
name = "main"
subnet_ids = [aws_subnet.frontend.id, aws_subnet.backend.id]
}
resource "aws_subnet" "frontend" {
availability_zone = var.az_a
vpc_id = var.vpc_id
cidr_block = "10.0.1.0/24"
}
resource "aws_subnet" "backend" {
availability_zone = var.az_b
vpc_id = var.vpc_id
cidr_block = "10.0.2.0/24"
}
Explanation:
- Before: The
backendsubnet's/0CIDR is not supported by AWS, so this configuration cannot be deployed. - After: The two subnets use valid private address ranges in different Availability Zones of the same VPC. Also verify actual routing and access controls; correcting address ranges does not establish isolation.