Skip to content

Commit

Permalink
Postgres on AWS RDS + EKS
Browse files Browse the repository at this point in the history
  • Loading branch information
the-gigi committed Sep 3, 2024
1 parent a1e682c commit c0ebc98
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
130 changes: 130 additions & 0 deletions content/posts/2024/09/postgres-rds-eks/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
+++
title = 'Postgres on AWS RDS + EKS'
date = 2024-09-02T15:53:30-07:00

+++

You have an AWS EKS cluster ⎈ and your workloads use a managed Postgres DB 🌐 deployed on AWS RDS.
You need to access it from your laptop using your favorite DB visualization tool. What's the best
way to do it 🤷 ?

Keep reading to find out...

<!--more-->

![](postgres-rds-eks.png)

# Prior Art 🎨

A few months ago I published a blog post on accessing a Postgres DB deployed on directly on your k8s
cluster - [Postgres on K8S](https://the-gigi.github.io/gigi-zone/posts/2024/05/postgres-on-k8s/).

The major difficulty is that the Postgres DB is not directly accessible from the internet. The basic
idea is to launch a pod with psql Postgres client and then use `kubectl exec` to access this pod
from your laptop and gain access to the DB 💪.

This is cool 😎, but it's not going to cut it if we want to visually browse the DB using a tool like
DBeaver or the database tool in JetBrains IDEs.

# Getting visual 👁️

What we really need is a proxy running on the EKS cluster that will forward the Postgres traffic to
the RDS instance. Then, we can perform `kubectl port-forward` on the proxy and get direct connection
from our laptop to our Postgres DB.

Here is the plan 🧠:

- Fetch the endpoint of the RDS instance or proxy
- Deploy a postgres proxy pod on the EKS cluster
- Port-forward the proxy pod or the external name service to your laptop
- Fetch the username and password
- Connect to the DB using your favorite visual DB tool with the Postgres credentials

## Fetch the IP address of the RDS instance or proxy

We will use the AWS CLI to fetch the IP address of the RDS instance or proxy and also jq for minor
formatting. If you are command-line challenged you are in the wrong place, buddy 🤷.

You need to have the AWS CLI installed and configured with the appropriate profile that has
permissions to access the RDS instance or proxy.

Here is the command to fetch the endpoint of an RDS instance:

```shell
ENDPOINT=$(aws rds describe-db-instances \
--db-instance-identifier <db-instance-identifier> \
--query 'DBInstances[0].Endpoint.Address' \
--profile <aws-profile> | jq -r)
```

Here is the command to fetch the endpoint of an RDS proxy:

```shell
ENDPOINT=$(aws rds describe-db-proxy-endpoints \
--db-proxy-endpoint-name <db-proxy-endpoint-name> \
--query 'DBProxyEndpoints[0].Endpoint' \
--profile <aws-profile> | jq -r)
```

## Deploy a postgres proxy pod on the EKS cluster

We will use
the [alpine/socat](https://github.com/alpine-docker/multi-arch-docker-images/tree/master/socat)
image to create a pod that will forward the Postgres traffic to the RDS instance or proxy. Here is
the command to create the pod (assuming the port is the standard 5432).

```shell
kubectl run postgres-proxy \
-n default \
--context <kube-context> \
--image docker.io/alpine/socat \
-- \
tcp-listen:5432,fork,reuseaddr \
tcp-connect:${ENDPOINT}:5432
```

I used the `default` namespace because it always exists. Later, we will discuss the choice of
namespace in the context of security.

## Port-forward the proxy pod to your laptop

Now, we can port-forward the proxy pod to our laptop. Here is the command to do it:

```shell
kubectl port-forward -n default --context <kube-context> postgres-proxy 5432:5432 &
```

This will run in the background, and you can now connect to the Postgres DB from your laptop
at http://localhost:5432

## Fetch the username and password

But, wait! We need the username and password to connect to the DB. It's up to you to decide where
you keep these precious credentials. You can store them in a Kubernetes secret in some namespace, or
maybe you keep the secrets in AWS secret manager 🙈.

Regardless, you need to fetch the username and password and use them to connect to the DB. Let's
discuss it in the context of security.

# Security 🛡️

OK. Connecting to a private RDS instance from your laptop is not the most secure thing to do. The
first rule of accessing your postgres DB directly is: **Don't do it!**. 🚫

Alright, you are still here, so let's discuss how to do it with some semblance of securely awareness
at least. First, make sure you are in a somewhat secure environment. If you are in a coffee shop or
some other public place using public networks, you are already in trouble.

Next, let's consider how to minimize the risk. Here are a few ideas:

- Use a dedicated Postgres user with limited permissions (ideally just read-only permissions) to
access the DB
- Grant the Postgres user access only for the duration of your interactive session and revoke
- When you fetch the username and password, do it in a sub-shell and copy directly to the clipboard.

# Web-based Postgres Access 🕸️

If you have a lot of users that need to access your database you may want to consider a web-based DB
tool like [Apache Superset](https://superset.apache.org)
or [Metabase](https://github.com/metabase/metabase). These tools can be deployed on your EKS cluster
and provide a web-based interface to your Postgres DB.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c0ebc98

Please sign in to comment.