IAM access to PostgreSQL databases
For background information on the database choices, please read the RFC for RDBMS in the Golden Path.
IAM access to PostgreSQL
The iam_database_authentication_enabled
flag is set to true
in both the postgres_aurora
and postgres_aurora_serverless
module supplied as part of Golden Path. The AWS documentation explains more about the benefits and limitations when using IAM access to your database, please review this before continuing.
Future
This first version of the documentation will set up the database user and connect from a dedicated EC2 instance to show the step-by-step required to connect to your database. Connecting from localhost with IAM access will be covered later once #65 is done.
Prerequisites
- A PostgreSQL database and a user capable of adding new users (as the one supplied by Golden Path setup)
- EC2 instance - for demonstrating the IAM functionality only. This will be void once
Connection to PostgreSQL from localhost
is done - Create a EC2 instance in the correct VPC where your DB cluster is set up
- Ubuntu is fine
- Choose the VPC where your infrastructure is set up
- Choose a public subnet to get a public IP address
- Remember to create a keypair and download it
- Go to the VPC where you created your EC2 instance and update the security group for the instance
- Allow inbound SSH from your IP address
- Allow outbound rules to all outbound
- Update PostgreSQL cluster to allow connection from EC2: Actions > Set up EC2 connection
- This will set up a security group that connects the EC2 instance with your RDS instance
- Choose the EC2 instance you just created
- SSH to the box:
ssh -i "YOUR-KEY-FILE.pem" ubuntu@X.Y.Z.A
. Keep this connection open for the step by step below- Install PostgreSQL client:
sudo apt-get install postgresql-client-14
Step by step
Enable IAM authentication
- If the
IAM DB authentication
flag under clusterConfiguration
is set toEnabled
: no action is needed - Otherwise: run
terraform get -update
andtf apply
to enable IAM authentication
Connect to PostgreSQL
From the EC2 instance: Connect with the user set up by Golden Path, this user have rights to add another user and grant access
psql --host=YOUR-DATABASE-HTTP-ENDPOINT \
--port=5432 \
--username=db_username \
--password \
--dbname=postgres
- Values for
db_username
anddb_password
are located in AWS Parameter Store - The default database name is
postgres
if nothing else is configured. Do not confuse with DB instance ID
Create IAM user
Create a new user for your database. In this case mydbuser
will be used as an example, but the username should reflect the usage you intend for this user to have.
Grant the special rds_iam
role to the new user:
Grant access to database
You can grant different levels of access to the user, execute one of the following statements (or any other grants based on your requirement):
Full access to schema
Only access to one table
Access to all tables
Policy document
Given the following policy document in rds-connect-mypostgres-cluster-policy.json
(update with the correct ARN for your user):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:eu-west-1:[account-id]:dbuser:[DbiResourceId]/mydbuser"
]
}
]
}
To find the DbiResourceId
for your Resource:
Create the policy:
aws iam create-policy \
--policy-name rds-connect-mypostgres-cluster-policy \
--policy-document file://rds-connect-mypostgres-cluster-policy.json
Create role
Create a role and attach the following policy stored in assume-role-policy.json
:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AssumeRolePolicy",
"Effect": "Allow",
"Principal": {"AWS": "[account-id]"},
"Action": "sts:AssumeRole"
}]
}
aws iam create-role \
--role-name rds-assume-mydbuser-mypostgres-cluster \
--assume-role-policy-document file://assume-role-policy.json
Attach the rds-connect-mypostgres-cluster-policy
created to that role:
aws iam attach-role-policy \
--policy-arn arn:aws:iam::[account-id]:policy/rds-connect-mypostgres-cluster-policy \
--role-name rds-assume-mydbuser-mypostgres-cluster
Now there is a role that can be assumed at a later point. You can check that everything is in order by running:
aws sts assume-role \
--role-arn "arn:aws:iam::[account-id]:role/rds-assume-mydbuser-mypostgres-cluster" \
--role-session-name assume-mydbuser-mypostgres-cluster
Connect with IAM to PostgreSQL
Switch to your local machine where you have awscli
set up and run the following:
export RDSHOST="YOUR-DATABASE-HTTP-ENDPOINT"
export PGPASSWORD="$(aws rds generate-db-auth-token \
--hostname $RDSHOST \
--port 5432 \
--region eu-west-1 \
--username mydbuser)"
echo $PGPASSWORD
Copy the PGPASSWORD
for later usage.
Download the certificate for RDS
On the EC2 instance where you will connect to PostgreSQL, download the certificate:
Connect to RDS
Export PGPASSWORD
from your local machine to the EC2 instance:
and connect to PostgreSQL: