I want my django application connect to RDS postgres using IAM authentication. That means the db password expires every 15min and should be re-generated. The problem is how can I change the database password in the runtime? Or should I update my database URL environment?
You can activate IAM database authentication by using the Amazon RDS console, AWS Command Line Interface (AWS CLI), or the Amazon RDS API. If you use the Amazon RDS console to modify the DB instance, then choose Apply Immediately to activate IAM database authentication right away.
IAM database authentication works with MariaDB, MySQL, and PostgreSQL. With this authentication method, you don't need to use a password when you connect to a DB instance. Instead, you use an authentication token. An authentication token is a unique string of characters that Amazon RDS generates on request.
We implemented a package for this functionality and published to PyPi. You can check it here https://github.com/labd/django-iam-dbauth
But in principle here are the steps:
First enable IAM Authentication.
Then add the policy and attach it to the role or user that connects to the DB.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:us-east-2:1234567890:dbuser:db-ABCDEFGHIJKL01234/db_userx"
]
}
]
}
Then create a user on your AWS postgres and grant rds_iam
role to it:
CREATE USER db_userx WITH LOGIN;
GRANT rds_iam TO db_userx;
For Django, you need a custom backend to allow generating credentials on the fly.
Create a package such as your.package.postgresql
with a base.py
in it
import boto3
from django.db.backends.postgresql import base
class DatabaseWrapper(base.DatabaseWrapper):
def get_connection_params(self):
params = super().get_connection_params()
rds_client = boto3.client("rds")
params["password"] = rds_client.generate_db_auth_token(
DBHostname=params.get("host", "localhost"),
Port=params.get("port", 5432),
DBUsername=params.get("user") or getpass.getuser(),
)
return params
Then use a settings like:
DATABASES = {
"default": {
"HOST": "<hostname>",
"USER": "<user>",
"PORT": 5432,
"ENGINE": "your.package.postgresql"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With