In this blog, we will discuss possible ways to connect to an Amazon RDS database instance, placed in a private subnet in the AWS cloud, from an external VPC without using the regular AWS endpoint.
What is the AWS PrivateLink?
AWS PrivateLink provides a secure method for private connectivity between Amazon VPCs, AWS services, and on-premises applications on the AWS network. To enable communication with the service from your private subnets, you do not need to employ an Internet gateway, NAT device, public IP address, AWS direct connection, or an AWS Site-to-Site VPN connection. As a result, customers can simply and securely access services on AWS using Amazon’s private network, powering connectivity to AWS services through Amazon VPC endpoints. PrivateLink provides the same level of security and performance as virtual network appliances or custom traffic inspection algorithms.
When we create an interface VPC endpoint for a service in our VPC to use PrivateLink, we generate an Elastic Network Interface (ENI) with a private IP address in the subnet, which acts as an entry point for traffic destined for the service. Amazon PrivateLink service endpoints are shown in our VPCs as ENIs with private IPs.
Why do we need the AWS PrivateLink for RDS?
The Amazon Relational Database Service (RDS) is a managed SQL database service provided by Amazon Web Services (AWS). Amazon RDS supports an array of database engines to store and organize data. When we create a new RDS in our AWS management console, we obtain an endpoint that can be used to connect to the database instance:
If the database instance is deployed in a private subnet, we can access the endpoint from the VPC in which the RDS is created. However, what happens if we want to connect to a database from another AWS network? In this case, there are several options.
- VPC peering
- VPN connection
- AWS PrivateLink
VPC peering and VPN connections are commonly used solutions; however, in most cases, they allow the entire traffic, and there might be complications around the configuration, overlapping CIDR blocks, security, etc.
If we want to allow database connections only, AWS PrivateLink is very handy and easy to configure.
Components
In this tutorial we will explain how to connect a private AWS RDS database instance, in account A from an external AWS VPC in account B.
Let us start with the components that we need to build a solution.
- VPC in account A
- VPC in account B
- RDS in account A – for this tutorial, we are going to use Aurora MySQL Serverless and make sure it is in private subnets in VPC-A
- Network Load Balancer (NLB) in account A with the RDS instance as a target group
- VPC endpoint service pointed to the NLB in account A
- VPC endpoint in account B (VPC-B) that is pointed to the VPC endpoint service in account A.
Configuration
VPC
Here, we used a standard configuration with private subnets, and NAT gateways. Internet gateways (IGW) and public subnets are not required, but they do not affect the functionality, so please feel free to set them up depending on your use case.
RDS
RDS must be in private subnets, and public access should be disabled. We did not connect using the default endpoints created by the AWS. An important part is to allow the CIDR of VPC-B on the RDS security group in account A:
NLB
We need to create a target group with the database instance private IP address and then configure the network load balancer with it.
- Target group settings
Type: IP address
Name: RDS-A
VPC: VPC-A
Protocol: TCP
Port: 3306
When an actual target is added, the private IP address of the RDS instance must be used. This can be performed with the nslookup command on the default AWS endpoint:
Our target group looks as follows:
- NLB configuration
Type: Network Load Balancer
Name: RDS-A-NLB
VPC: VPC-A
Scheme: Internal
Mappings: select all zones and assign the private subents
Listener protocol: TCP
Listener port: 3306
Listener default action: Forward to RDS-A (make sure to select
your target group)
The NLB looks as follows:
It should be noted that port 3306 is specific to MySQL. If you use another type of database, please ensure that the specified port is set.
VPC Endpoint service
Here, we only need to create a VPC endpoint service in account A and point it to our network load balancer (RDS-A-NLB). It is recommended that the acceptance-required option be ticked.
When a service is created, it should be selected and navigated to the Allow principal section. There, you need to allow the ARN of the user on the other account (account B):
Please ensure that the correct account ID and users are set.
In the screenshot above, the endpoint service name can also be seen. This will be needed later for VPC endpoint creation.
VPC Endpoint
This is the endpoint we need to create in account B (from which we will access the database). Please ensure that you are in the same AWS region. We also need to specify the correct VPC (VPC-B) and the subnets.
When the endpoint is created, return to the VPC endpoint service in account A and accept the connection:
Our VPC endpoint should be available thereafter.
We can then simply copy the DNS name of the VPC endpoint and use it for database connections.
And that’s all! Now, we can easily connect our database in account A from account B using our new endpoint.
Conclusion
AWS PrivateLink is a great way to connect specific resources privately and securely if one does not want to allow the entire network traffic. It can help build secure, scalable, and highly available architectures for services on AWS. Consider your application’s connectivity requirements before choosing an Amazon VPC connectivity architecture for internal and external customers.
2 Responses
Your article provided important information and deep knowledge on a subject I am interested in.
I have a problem, can you help me?
I followed the steps in the article, but I not connection to RDS aws at VPC private A from EC2 at VPC private B.
I’m creating VPC endpoint in same account, so is this a problem?
Looking forward to your response
Hi Long Vo,
I’m happy to hear about your interest and I’ll do my best to assist but I’ll need some information first. Would you be able to answer the following questions:
1. Have you configured a network load balancer (NLB) with the internal database IPs as targets. If yes, are the targets appearing as healthy in your AWS console?
2. Are the CIDRs of the VPCs overlapping?
3. When you try to setup PrivateLink in the destination account, are you able to see the source VPC endpoint service? If no, please have in mind that both VPCs need to be in the same AWS region.
4. Have you allowed the access between the accounts when configuring the VPC endpoint service?
Those are usually the most common mistakes but any additional information will be helpful. You can send us some screenshots with your current configuration or any error messages that you get.