Skip to main content

Securely connect to an Amazon RDS via PrivateLink using SQL

· 3 min read
Yolanda Robla
L. Fernando De Pombo

Do you have some database instances on RDS and wonder what's the most secure way to reach them? In this post, we will walk you through how to securely connect to an AWS RDS instance using PrivateLink and IaSQL. AWS PrivateLink provides private connectivity between virtual private clouds (VPCs), supported AWS services, and your on-premises networks without exposing your traffic to the public internet. IaSQL is an open-source software tool that creates a two-way connection between an unmodified PostgreSQL database and an AWS account so you can manage your infrastructure from a database.

When creating a database, AWS provides some specific information about the hostnames and ports used. You can access those to reach your databases by using specific clients for MySQL, Postgres, etc...:

On a public VPC, those endpoints will be public by default. However, consider creating them under a private VPC and accessing them internally, to grant additional security to critical services. AWS PrivateLink offers the possibility to securely access those services without exposing them to the internet, just using Amazon's private network.

Are my RDS instances properly configured?

Please use this query to check it:

Run SQL to check your endpoints
 ---- Installing the needed modules
SELECT
iasql_install ('aws_rds', 'aws_vpc');

-- Perform the query for endpoints
SELECT
rds.region,
vpc.is_default,
vpc.cidr_block,
(
SELECT
COUNT(*) > 0
FROM
endpoint_interface
WHERE
endpoint_interface.region = rds.region
AND service = 'rds'
AND endpoint_interface.vpc_id = vpc.id
) AS has_endpoint_interface
FROM
rds
LEFT OUTER JOIN vpc ON vpc.region = rds.region;

Have you found missing endpoints? No problem, IaSQL can generate missing Endpoint Interfaces for you:

Add missing endpoint interfaces
SELECT
*
FROM
iasql_begin ();

-- Inserts the missing endpoints
INSERT INTO
endpoint_interface (region, vpc_id, service, private_dns_enabled)
SELECT
RDS.region,
vpc.id,
'rds',
TRUE
FROM
rds
INNER JOIN vpc ON rds.region = vpc.region
WHERE
NOT EXISTS (
SELECT
id
FROM
endpoint_interface
WHERE
endpoint_interface.region = rds.region
AND endpoint_interface.vpc_id = vpc.id
);

-- Preview the changes
SELECT
*
FROM
iasql_preview ();

-- Apply the changes
--select * from iasql_commit();
-- Rollback the changes
select * from iasql_rollback();

Running this query on an IaSQL database will auto-generate the missing endpoint interfaces and will allow you to preview the changes to be applied on your cloud. Once you are OK with the results, you can uncomment the iasql_commit query, comment the iasql_rollback query, and it will create the endpoints for you. If the final results in the cloud are not as expected, you can always roll back your changes by calling the iasql_rollback command.

Testing the result

After running the query, you should have Endpoint Interfaces created for your RDS resources. Those should be on the region and VPC where you had your databases:

To start testing the result, you can start a new EC2 instance on a private VPC in the same region where your RDS and Endpoint interface is configured. You can double-check that there is no internet connectivity. But the RDS endpoint could still be reached, by using the interface that has been created:

Please note that you could only use those endpoints from the same region. You could reach the services in multiple regions with the use of VPC peering