Diagnosing AWS EC2 to RDS Network Issues

Posted by Aug on February 28, 2024

I’ve learned a few things while helping out a project implement logins and persistence on Spring, deployed on AWS EC2 + Postgres on AWS RDS.

Network Connectivity BS

The biggest pain for EC2 + RDS is having them communicate with each other properly. I have a Spring server deployed inside a docker container on EC2, and a Postgres DB deployed as RDS.

Scenario

EC2 and RDS are in the same Availability Zone. Spring server in docker container was started with a public DNS 1.1.1.1, which meant the RDS endpoint (given as a fully qualified domain name) resolved to the public IP inside the docker container (3.1.x.x). This needs to be fixed before connectivity can be established as I disallowed public IP for the DB.

These are the tools I used to diagnose connectivity:

nslookup - to show what ip the db hostname resolves to

nslookup dbhost.ap-southeast-1.rds.amazonaws.com

nc - to test connectivity to a specific port

nc -zv dbhost.ap-southeast-1.rds.amazonaws.com 5432

psql - to connect to the database with db client

psql --host=dbhost.ap-southeast-1.rds.amazonaws.com --port=5432 --dbname=postgres --username=postgres

You will need to run these tools and compare the outputs from the ec2 host and from the docker container running in the ec2 host.

To run commands inside the docker container, find the container name via docker ps, then launch shell (my container name is backend):

docker exec -it backend /bin/bash

Resolution

Testing connectivity from the host to Postgres RDS worked fine (using nc) but failed when done inside the docker container.

On the docker host, nslookup to the db FQDN resolved to the private ip (10.x.x.x.).

In the docker container, the same nslookup resolved to the public ip (3.1.x.x).

Two things needed to be done to allow connections from the Spring server in the docker container in EC2 to the Postgres RDS instance:

  • An inbound rule needed to be added to the RDS instance to allow traffic from 10.0.0.0/24 using Postgres IPV4 (the private CIDR range shared EC2 and RDS). Without this the nc test from the host failed.

  • The Spring server needs to use the private network DNS

For reference here’s the command to use the AWS private DNS (10.0.0.2) so that the RDS FQDN endpoint can resolve to the private IP properly. I used ChatGPT to help me figure out what the DNS should be given my AWS network config:

` docker run -d –restart unless-stopped –dns “10.0.0.2” -e “SPRING_PROFILES_ACTIVE=aws” -e “OPENAPI_SERVER_URL=https://develop.lyla.travelbox.tech” –name backend -p 8080:8080 docker.io/library/lyla-backend:0.0.1-SNAPSHOT || exit 4 `