DEV Community

How I Made RDS Private Without Extra Cost Using Egress-Only IGW

I had an Amazon RDS DB instance with public access enabled due to certain requirements. When public access was no longer needed, I migrated it to a private subnet.

By using an Egress-Only Internet Gateway (Egress-Only IGW), I completed the migration without adding paid resources like NAT Gateways or VPC endpoints.

In this article, I'll share the background and the actual migration steps.

Background

The reason I wanted to move the DB to a private subnet was that public access was no longer required.

Public access had been enabled because Lambda functions in multiple AWS accounts needed to access this DB. While VPC peering was an option, I chose simple public access since IAM authentication alone seemed sufficient.

Later, the requirements changed—only Lambda functions in the same account as the DB needed access. This meant I could finally migrate to a private subnet.

The Challenge: Connecting to AWS Service Endpoints

However, there was one hurdle to overcome: "How do Lambda functions connect to AWS service endpoints?"

The Lambda functions needed to access not only the DB but also AWS service endpoints—specifically Athena, STS, and CloudWatch.

Attaching a VPC to the Lambda function would enable access to the DB in the private subnet. But it would also cut off the route to service endpoints.

My first thought was to use paid NAT Gateways or VPC endpoints. But I wanted to complete the migration without adding costs if possible.

Egress-Only IGW: A Cost-Free Solution

After some thought, I came up with the solution: Egress-Only IGW. It has the following characteristics:

  • Used only for IPv6 traffic
  • Allows outbound communication from VPC to the internet (inbound connections cannot be initiated from the internet)
  • No charge

This means if the AWS service endpoints support IPv6, Lambda functions with VPC attached can connect to them for free.

You can check IPv6 support for service endpoints in this documentation.

Athena, STS, and CloudWatch all support IPv6 (note: the STS global endpoint does not support IPv6; regional endpoints are required), so the following migration should be possible:

Component Before After
DB instance Public subnet Private subnet
Lambda → DB Internet Within VPC
Lambda → AWS services IPv4 IPv6 (via Egress-Only IGW)

Migration Steps

With the goal set, I proceeded with the following steps:

  1. Add IPv6 support to the VPC
  2. Update Lambda function configuration
  3. Migrate DB to private subnet
  4. Delete unnecessary resources

1. Add IPv6 Support to the VPC

First, I added IPv6 support to the VPC, including associating CIDR blocks and updating route tables. See the documentation for details.

2. Update Lambda Function Configuration

Next, I updated the Lambda function configuration. Key points:

  • Allow IPv6 egress in the security group
  • Set the environment variable AWS_USE_DUALSTACK_ENDPOINT=true (reference)
  • Attach VPC and enable "Allow IPv6 traffic for dual-stack subnets" (reference)

The environment variable tells boto3 (used by the Lambda function) to send requests to IPv4/IPv6 dual-stack service endpoints.

3. Migrate DB to Private Subnet

Then, I migrated the DB to the private subnet. This was the main task.

I expected it to be simple, but you cannot directly migrate a DB from a public subnet to a private subnet. It required some extra steps.

Specifically, you need to follow steps like "disable Multi-AZ → edit subnet group → enable Multi-AZ → ..." See this article for details.

After migration, I edited the DB's security group:

  • Before: Allow access from 0.0.0.0/0
  • After: Allow access from the Lambda function's security group

4. Delete Unnecessary Resources

Finally, I deleted the now-unnecessary public subnet and the regular Internet Gateway. Migration complete.

Conclusion

That's how I used Egress-Only IGW to make RDS private without extra cost. It was a great opportunity to work with this feature in a real-world scenario.

This example used Lambda, but the approach should apply to other services like ECS as well—assuming the target endpoints support IPv6.

If you're choosing a public subnet due to cost-security trade-offs, Egress-Only IGW might be your solution. Give it a try!

Top comments (0)