Skip to main content

DMS Replication Instance Is Not Publicly Exposed to the Internet

Overview

This check identifies AWS Database Migration Service (DMS) replication instances that are publicly accessible from the internet. A replication instance is considered exposed when both of these conditions are true:

  1. The PubliclyAccessible setting is enabled
  2. An attached security group allows inbound traffic from any address (0.0.0.0/0 or ::/0)

DMS replication instances handle sensitive database migration traffic. Keeping them private protects your data during migration.

Risk

Severity: Critical

Publicly accessible replication instances create serious security risks:

  • Data theft: Migration data and database credentials can be intercepted or stolen
  • Data tampering: Attackers may alter migration tasks or inject malicious records into your databases
  • Service disruption: DDoS attacks can halt replication and delay your migration cutover

Remediation Steps

Prerequisites

You need permission to modify DMS replication instances and EC2 security groups in your AWS account.

Required IAM permissions

Your IAM user or role needs these permissions:

  • dms:DescribeReplicationInstances
  • dms:ModifyReplicationInstance
  • ec2:DescribeSecurityGroups
  • ec2:RevokeSecurityGroupIngress
  • ec2:AuthorizeSecurityGroupIngress

AWS Console Method

Step 1: Identify exposed replication instances

  1. Open the AWS DMS Console
  2. Review each replication instance
  3. Click on an instance to view its details
  4. Note instances where Publicly accessible shows "Yes"

Step 2: Fix security group rules (quick fix)

For each exposed instance:

  1. In the instance details, find VPC security groups
  2. Click on each security group ID to open it in a new tab
  3. Select the Inbound rules tab
  4. Look for rules with source 0.0.0.0/0 or ::/0
  5. Click Edit inbound rules
  6. Delete or replace overly permissive rules:
    • Remove rules allowing all IPs
    • Add rules that only allow specific IP addresses or CIDR ranges that need access
  7. Click Save rules

Step 3: Disable public accessibility (recommended)

For a more secure configuration, disable public access entirely:

  1. Return to the DMS Replication Instances page
  2. Select the instance checkbox
  3. Click Actions > Modify
  4. Scroll to Network and security
  5. Set Publicly accessible to No
  6. Click Modify

Important: Disabling public access causes the instance to restart. Plan for a brief interruption to any running migration tasks.

AWS CLI (optional)

List all replication instances and their public access status:

aws dms describe-replication-instances \
--region us-east-1 \
--query 'ReplicationInstances[*].[ReplicationInstanceIdentifier,PubliclyAccessible,VpcSecurityGroups[*].VpcSecurityGroupId]' \
--output table

Get the ARN of a specific replication instance:

aws dms describe-replication-instances \
--region us-east-1 \
--filters Name=replication-instance-id,Values=<your-instance-id> \
--query 'ReplicationInstances[0].ReplicationInstanceArn' \
--output text

Check security group rules for overly permissive access:

aws ec2 describe-security-groups \
--region us-east-1 \
--group-ids <security-group-id> \
--query 'SecurityGroups[*].IpPermissions[?contains(IpRanges[*].CidrIp, `0.0.0.0/0`)]' \
--output json

Remove an overly permissive inbound rule:

aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <security-group-id> \
--protocol tcp \
--port <port-number> \
--cidr 0.0.0.0/0

Modify the replication instance to disable public access:

aws dms modify-replication-instance \
--region us-east-1 \
--replication-instance-arn <replication-instance-arn> \
--no-publicly-accessible \
--apply-immediately

Replace:

  • <your-instance-id> with your replication instance identifier
  • <security-group-id> with the VPC security group ID
  • <port-number> with the port to restrict
  • <replication-instance-arn> with the full ARN of the instance
CloudFormation (optional)

Use this template to create a secure DMS replication instance with public access disabled:

AWSTemplateFormatVersion: '2010-09-09'
Description: Secure DMS Replication Instance

Parameters:
ReplicationInstanceIdentifier:
Type: String
Description: Unique identifier for the replication instance
ReplicationInstanceClass:
Type: String
Default: dms.t3.micro
Description: Instance class for the replication instance
SubnetGroupIdentifier:
Type: String
Description: Identifier for the replication subnet group
VpcSecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Description: List of VPC security group IDs

Resources:
SecureDMSReplicationInstance:
Type: AWS::DMS::ReplicationInstance
Properties:
ReplicationInstanceIdentifier: !Ref ReplicationInstanceIdentifier
ReplicationInstanceClass: !Ref ReplicationInstanceClass
PubliclyAccessible: false
ReplicationSubnetGroupIdentifier: !Ref SubnetGroupIdentifier
VpcSecurityGroupIds: !Ref VpcSecurityGroupIds

Outputs:
ReplicationInstanceArn:
Description: ARN of the replication instance
Value: !Ref SecureDMSReplicationInstance

Key security settings:

  • PubliclyAccessible: false ensures the instance stays private
  • ReplicationSubnetGroupIdentifier should reference private subnets
  • VpcSecurityGroupIds should reference security groups with restrictive rules
Terraform (optional)

Use this configuration to create a secure DMS replication instance:

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "replication_instance_id" {
description = "Unique identifier for the replication instance"
type = string
}

variable "replication_instance_class" {
description = "Instance class for the replication instance"
type = string
default = "dms.t3.micro"
}

variable "replication_subnet_group_id" {
description = "Identifier for the replication subnet group"
type = string
}

variable "vpc_security_group_ids" {
description = "List of VPC security group IDs"
type = list(string)
}

resource "aws_dms_replication_instance" "secure_instance" {
replication_instance_id = var.replication_instance_id
replication_instance_class = var.replication_instance_class
publicly_accessible = false
replication_subnet_group_id = var.replication_subnet_group_id
vpc_security_group_ids = var.vpc_security_group_ids

tags = {
Name = var.replication_instance_id
}
}

output "replication_instance_arn" {
description = "ARN of the replication instance"
value = aws_dms_replication_instance.secure_instance.replication_instance_arn
}

Key security settings:

  • publicly_accessible = false keeps the instance private
  • replication_subnet_group_id should reference private subnets
  • vpc_security_group_ids should list security groups with least-privilege rules

Verification

After making changes, verify the fix:

  1. Return to the DMS Replication Instances page
  2. Click on your replication instance
  3. Confirm Publicly accessible shows "No"
  4. Check that attached security groups no longer have 0.0.0.0/0 inbound rules
CLI verification commands

Check public accessibility status:

aws dms describe-replication-instances \
--region us-east-1 \
--filters Name=replication-instance-id,Values=<your-instance-id> \
--query 'ReplicationInstances[0].PubliclyAccessible' \
--output text

Expected output: False

Verify security group has no open inbound rules:

aws ec2 describe-security-groups \
--region us-east-1 \
--group-ids <security-group-id> \
--query 'SecurityGroups[*].IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]' \
--output json

Expected output: [] (empty array)

Run the Prowler check to confirm the fix:

prowler aws --checks dms_instance_no_public_access

Additional Resources

Notes

  • Downtime consideration: Modifying the PubliclyAccessible setting causes the replication instance to restart. Schedule this change during a maintenance window if migrations are running.

  • Private subnet requirement: For instances with public access disabled, ensure your replication subnet group uses private subnets with proper routing to reach source and target databases.

  • Alternative connectivity: If you need to access DMS from on-premises networks, use AWS VPN, VPC peering, AWS Direct Connect, or AWS PrivateLink instead of public internet access.

  • Security group best practices: Only allow inbound traffic from specific IP ranges that genuinely need access. Common patterns include allowing only the source database IP and target database IP.

  • Compliance frameworks: This check maps to AWS Foundational Security Best Practices, PCI DSS, C5, and KISA-ISMS-P requirements.