Skip to content

IAM Authentication for AWS RDS Postgres

Austin Culter edited this page Jul 25, 2024 · 1 revision

Requirements

In order to migrate an existing Sal deployment's AWS RDS (Postgres) authentication method from password-based to IAM-based, the following conditions will need to be met by your deployment environment:

  1. You must be deploying Sal as a container
  2. You must be running a Sal release >= 4.3.0
  3. You should be running Postgres Engine version >= 15.5[1]
  4. You have read and understood -- and your environment will not be affected by -- the Limitations for IAM database authentication
  5. Your environment must allow for the Sal container(s) to assume an IAM Role[2] and gain a fresh STS token[3]

[1] While AWS supports IAM Auth as far back as RDS for Postgres 10, this feature was only tested as far back as Engine version 15.5

[2] How this is achieved is dependent on your architecture and is on you to figure out within your environment's constraints

[3] The container must have a STS token in order for the django-iam-dbauth custom database wrapper to perform the necessary database authentication token generation process

Procedure

As always, it is advisable to test the following in a development environment before making these changes in production.

  • Modify your RDS database configuration to enable 'Password and IAM database authentication' (under 'Database authentication') and 'Apply immediately'
  • Create a new Postgres user (this doc will refer to the user as salawsiam but call it whatever you want), grant it the rds_iam role (which enables IAM auth for that specific user) and permission it exactly like your pre-existing database user (the one using password-based auth):
CREATE USER salawsiam;
GRANT rds_iam TO salawsiam;
GRANT ALL PRIVILEGES ON DATABASE sal to salawsiam;
GRANT rds_superuser to salawsiam;
  • Create a new IAM Policy which permits the ability to:
    • Perform rds-db:connect (as the newly created salawsiam Postgres user) on your target RDS database
      • Note: <YourRDSDatabaseResourceID> != <YourRDSDBIdentifier>!
    • Perform rds:DescribeDBInstances, rds:DescribeDBCluster and rds:DescribeDBEngineVersions on your all RDS databases

Example AWS IAM Policy:

{
    "Statement": [
        {
            "Action": [
                "rds-db:connect"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:rds-db:<YourRDSRegion>:<YourAWSAccountID>:dbuser:<YourRDSDatabaseResourceID>/salawsiam"
            ]
        },
        {
            "Action": [
                "rds:DescribeDBInstances",
                "rds:DescribeDBClusters",
                "rds:DescribeDBEngineVersions"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}
  • Create a new IAM Role and assign it the previously created IAM Policy
    • Ensure your IAM Role's 'Trusted Entities' permits your container to assume this role
  • Within your container's environment, ensure the following variables are set:
AWS_IAM="true"
AWS_RDS_REGION ="us-west-2" # Or whatever region your RDS database exists in
DB_NAME="sal"
DB_USER="salawsiam" # Or whatever you decided to call your Postgres user (the one granted `rds_iam` role)
DB_HOST="sal-sandbox.abcdefghijk0.us-west-2.rds.amazonaws.com"
DB_PORT="5432" # Or whatever port your database is configured to use
  • Test, test, test
  • Profit
Clone this wiki locally