blob: 14d5508936c18d3e67cddeec957d2db649863c0c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
---
title: Opening multiple DB tunnels with AWS SSM
date: 2024-06-26
extra:
kind: note
---
To open a tunneled connection to an AWS managed database, such as RDS or DocumentDB, the commonly recommended way is to use a bastion host and `aws ssm start-session`. The bastion host is an EC2 instance that is in the same VPC as your database. The AWS CLI command allows you to connect to SSM-enabled EC2 instances from your development machine using IAM authorization, without having to manage SSH keys.
The script below connects to the specified PostgreSQL RDS and DocumentDB instances using a bastion host. Both databases will be accessible on a `localhost` port. Modify as necessary.
```bash
#!/bin/bash
# Configure to match your environment
BASTION_NAME="<YOUR_BASTION_INSTANCE_NAME>"
DOCDB_CLUSTER_NAME="<YOUR_DOCDB_CLUSTER_NAME>"
PG_CLUSTER_NAME="<YOUR_RDS_CLUSTER_NAME>"
DOCDB_PORT="27017"
PG_PORT="5432"
# Fail on errors, do not allow use of unset variables
set -eu
# Colors for nicer output
BB="\\033[34m"
RST="\\033[0m"
# Fetch the endpoints URIs and bastion instance ID
DOCDB_ENDPOINT=$(aws docdb describe-db-clusters --db-cluster-identifier "${DOCDB_CLUSTER_NAME}" --query "DBClusters[0].Endpoint" --output text)
PG_ENDPOINT=$(aws rds describe-db-clusters --db-cluster-identifier "${PG_CLUSTER_NAME}" --query "DBClusters[0].Endpoint" --output text)
BASTION_INSTANCE=$(aws ec2 describe-instances --filter "Name=tag:Name,Values=${BASTION_NAME}" --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" --output text)
echo "DocumentDB endpoint: ${DOCDB_ENDPOINT}"
echo "PostgreSQL endpoint: ${PG_ENDPOINT}"
echo "Bastion host instance ID: ${BASTION_INSTANCE}"
echo ""
echo -e "${BB}Starting SSM sessions with DocumentDB and PostgreSQL port forwarding in localhost in this terminal...${RST}"
# DocumentDB port forwarding
aws ssm start-session \
--target "${BASTION_INSTANCE}" \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"portNumber":["'${DOCDB_PORT}'"],"localPortNumber":["'${DOCDB_PORT}'"],"host":["'"${DOCDB_ENDPOINT}"'"]}' &
PID1=$!
# PostgreSQL port forwarding
aws ssm start-session \
--target "${BASTION_INSTANCE}" \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"portNumber":["'${PG_PORT}'"],"localPortNumber":["'${PG_PORT}'"],"host":["'"${PG_ENDPOINT}"'"]}' &
PID2=$!
cleanup() {
echo "Caught CTRL-C, stopping both tunnels..."
kill $PID1 $PID2
exit
}
# Catch the interrupt signal (CTRL-C)
trap cleanup INT
# Wait for both processes to exit
wait $PID1
wait $PID2
```
|