Skip to content

Commit e183538

Browse files
init
1 parent 36ee21b commit e183538

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

cmd/rds-iam-to-dsn/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# rds-iam-dsn
2+
3+
A CLI that resolves a `postgres+rds-iam://...` URL into a usable tokenized PostgreSQL DSN and prints it to stdout.
4+
5+
Use this when you want to script `psql`, `pg_dump`, or other Postgres tools without manual IAM token generation.
6+
7+
## Installation
8+
9+
```bash
10+
go install github.com/corbaltcode/go-libraries/cmd/rds-iam-dsn@latest
11+
```
12+
13+
Or build from source:
14+
15+
```bash
16+
cd ./cmd/rds-iam-dsn
17+
go build
18+
```
19+
20+
## Prerequisites
21+
22+
- **AWS credentials** configured (env vars, `~/.aws/credentials`, IAM role, etc.)
23+
- **AWS region** configured for SDK resolution (for example: `AWS_REGION`, shared config profile, or runtime role config)
24+
- **RDS IAM authentication enabled** on your database instance
25+
- A DB user configured for IAM auth (`CREATE USER myuser WITH LOGIN; GRANT rds_iam TO myuser;`)
26+
27+
## Usage
28+
29+
```bash
30+
rds-iam-dsn '<postgres+rds-iam-url>'
31+
```
32+
33+
- Database path is optional. If omitted, `pgutils` defaults DB name to the username.
34+
- The command prints the resolved DSN to **stdout**.
35+
36+
## Examples
37+
38+
Resolve DSN only:
39+
40+
```bash
41+
rds-iam-dsn 'postgres+rds-iam://app_user@mydb.abc123.us-east-1.rds.amazonaws.com:5432/myapp'
42+
```
43+
44+
Use with `psql` in a script:
45+
46+
```bash
47+
DSN="$(rds-iam-dsn 'postgres+rds-iam://app_user@mydb.abc123.us-east-1.rds.amazonaws.com:5432/myapp')"
48+
psql "$DSN"
49+
```
50+
51+
Or directly:
52+
53+
```bash
54+
psql "$(rds-iam-dsn 'postgres+rds-iam://app_user@mydb.abc123.us-east-1.rds.amazonaws.com:5432/myapp')"
55+
```
56+
57+
Use with `pg_dump`:
58+
59+
```bash
60+
DSN="$(rds-iam-dsn 'postgres+rds-iam://app_user@mydb.abc123.us-east-1.rds.amazonaws.com:5432/myapp')"
61+
pg_dump "$DSN" > myapp.sql
62+
```
63+
64+
Cross-account role assumption:
65+
66+
```bash
67+
rds-iam-dsn 'postgres+rds-iam://app_user@mydb.abc123.us-east-1.rds.amazonaws.com:5432/myapp?assume_role_arn=arn:aws:iam::123456789012:role/db-connect&assume_role_session_name=rds-iam-dsn'
68+
```
69+
70+
## Notes
71+
72+
- IAM auth tokens are short-lived (typically 15 minutes). Generate DSNs close to use time.
73+
- Treat emitted DSNs as secrets while valid.

cmd/rds-iam-to-dsn/main.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
"log"
8+
"os"
9+
10+
"github.com/corbaltcode/go-libraries/pgutils"
11+
)
12+
13+
func main() {
14+
if len(os.Args) != 2 {
15+
fmt.Fprintf(
16+
os.Stderr,
17+
"expected exactly one positional RDS IAM connection URL argument, got %d\nUsage:\n %s 'postgres+rds-iam://user@host:5432/db'\n",
18+
len(os.Args)-1,
19+
os.Args[0],
20+
)
21+
os.Exit(2)
22+
}
23+
rawURL := os.Args[1]
24+
25+
ctx := context.Background()
26+
27+
restoreLogger := suppressStdLogger()
28+
defer restoreLogger()
29+
30+
connectionStringProvider, err := pgutils.NewConnectionStringProviderFromURLString(ctx, rawURL)
31+
if err != nil {
32+
fmt.Fprintf(os.Stderr, "failed to create connection string provider: %v\n", err)
33+
os.Exit(1)
34+
}
35+
36+
dsnWithToken, err := connectionStringProvider.ConnectionString(ctx)
37+
if err != nil {
38+
fmt.Fprintf(os.Stderr, "failed to get connection string from provider: %v\n", err)
39+
os.Exit(1)
40+
}
41+
42+
// Print only the final DSN to stdout for command-substitution in scripts.
43+
fmt.Fprintln(os.Stdout, dsnWithToken)
44+
}
45+
46+
func suppressStdLogger() func() {
47+
prevOutput := log.Writer()
48+
prevFlags := log.Flags()
49+
prevPrefix := log.Prefix()
50+
51+
log.SetOutput(io.Discard)
52+
log.SetFlags(0)
53+
log.SetPrefix("")
54+
55+
return func() {
56+
log.SetOutput(prevOutput)
57+
log.SetFlags(prevFlags)
58+
log.SetPrefix(prevPrefix)
59+
}
60+
}

0 commit comments

Comments
 (0)