Back to Checks
aws

RDS instance is deployed in a VPC

rds_instance_inside_vpc
Service: rdsSeverity: high
OfficialBuilt-inVerified
Categories:trust-boundariesinternet-exposed
Resource Type:AwsRdsDbInstance

RDS DB instances are assessed for VPC placement by the presence of a vpc_id indicating deployment within a VPC.

Instances without this association are treated as outside VPC networking.

Risk

Without VPC isolation, databases may expose internet-reachable endpoints and lack granular network controls. This degrades confidentiality and availability via scanning/brute force and data exfiltration, and threatens integrity through unauthorized connections and lateral movement.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks rds_instance_inside_vpc

Recommendation

Deploy all RDS instances in a VPC, preferably in private subnets. Enforce least privilege with security groups, network ACLs, and restrictive routing. Use private connectivity (peering, VPN, Direct Connect), avoid public exposure, and apply defense in depth through segmentation and monitoring.

Remediation

CLI

aws rds modify-db-instance --db-instance-identifier <example_resource_id> --db-subnet-group-name <example_resource_name> --apply-immediately

Terraform

# Terraform: ensure RDS instance is in a VPC via DB subnet group
resource "aws_db_subnet_group" "<example_resource_name>" {
  name       = "<example_resource_name>"
  subnet_ids = [
    "<example_resource_id>", # CRITICAL: Subnets in the target VPC
    "<example_resource_id>"
  ]
}

resource "aws_db_instance" "<example_resource_name>" {
  identifier          = "<example_resource_id>"
  db_subnet_group_name = aws_db_subnet_group.<example_resource_name>.name  # CRITICAL: Places instance in a VPC
}

NativeIaC

# CloudFormation: move RDS instance into a VPC by assigning a DB subnet group
Resources:
  <example_db_subnet_group>:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: "subnets for rds"
      SubnetIds:
        - <example_resource_id>  # CRITICAL: Subnets in the target VPC
        - <example_resource_id>  # CRITICAL: At least two AZs recommended

  <example_db_instance>:
    Type: AWS::RDS::DBInstance
    Properties:
      DBSubnetGroupName: !Ref <example_db_subnet_group>  # CRITICAL: Ensures the DB instance is deployed in a VPC

Other

1In the AWS Console, go to RDS > Subnet groups and create/select a DB subnet group in the target VPC (with subnets in at least two AZs)
2Go to RDS > Databases, select the DB instance, click Modify
3Under Connectivity, set DB subnet group to the VPC subnet group from step 1 (select a VPC security group if prompted)
4Check Apply immediately and choose Continue > Modify DB instance

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.rds.rds_client import rds_client


class rds_instance_inside_vpc(Check):
    def execute(self):
        findings = []
        for db_instance in rds_client.db_instances.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=db_instance)
            if db_instance.vpc_id:
                report.status = "PASS"
                report.status_extended = f"RDS Instance {db_instance.id} is deployed in a VPC {db_instance.vpc_id}."
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"RDS Instance {db_instance.id} is not deployed in a VPC."
                )

            findings.append(report)

        return findings