RDS Authentication via IAM User/Role

I’ll keep this post a short one as it just gives an overview of enabling IAM based login to AWS RDS. Before we continue, please note:

Prerequisites

IAM database authentication is available for the following database engines and DB instance classes:

  1. MySQL 5.6, minor version 5.6.34 or higher.
  2. MySQL 5.7, minor version 5.7.16 or higher.
  3. PostgreSQL versions 10.6 or higher, 9.6.11 or higher, and 9.5.15 or higher.
  4. All DB instance classes are supported, except for db.t2.small and db.m1.small.
  5. IAM database authentication is not supported for MySQL 5.5 or MySQL 8.0.

Enabling IAM Auth for RDS

Alright, so if this is sorted, we can continue with the below steps:

  1. Enable IAM Authentication in existing RDS using the link here: Enabling and Disabling IAM Database Authentication

  2. Login to RDS with master username password.

    1
    mysql -h <RDS_ENDPOINT> --user <MASTER_USERNAME> --password
  3. Create Users with specific database access using the below commands:

    1
    2
    mysql> CREATE USER <USERNAME> IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
    mysql> grant all privileges on <DATABASE_NAME>.* to <USERNAME> IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
  4. Get the DB Identifier for IAM policy generation:

    1
    DB_ID="$(aws rds describe-db-instances --query 'DBInstances[?DBInstanceIdentifier==`<RDS_NAME>`].DbiResourceId' --output text)"
  5. Generate and Attach the policy for the IAM user:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": [
    "rds-db:connect"
    ],
    "Resource": [
    "arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<DB_ID>/<USERNAME>"
    ]
    }
    ]
    }
  6. Use the below script to connect to the RDS:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash

    # Get RDS endpoint
    RDS_ENDPOINT="$(aws rds describe-db-instances --query 'DBInstances[?DBInstanceIdentifier==`<RDS_NAME>`].Endpoint.Address' --output text)"

    # Get Temporary Token for Connection
    TOKEN="$(aws rds generate-db-auth-token --hostname $RDS_ENDPOINT --port 3306 --region <REGION> --username <USERNAME> --output text)"

    # Connect to RDS using the TOKEN
    mysql --host="$RDS_ENDPOINT" --port=3306 --enable-cleartext-plugin --user="<USERNAME>" --password="$TOKEN"

Notes

  • You can add access for more RDS instances (running in different regions) in a single IAM policy

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": [
    "rds-db:connect"
    ],
    "Resource": [
    "arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<DB_ID1>/<USERNAME1>",
    "arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<DB_ID2>/<USERNAME2>",
    "arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<DB_ID3>/<USERNAME3>"
    ]
    }
    ]
    }
    • USERNAME1 can have read only access to DB_ID1
    • USERNAME2 can have full admin access to entire DB_ID2
    • USERNAME3 can have admin access to DB_ID3 for single database only.
  • The <USERNAME> has to be created via admin privileges.

  • Add the proper endpoints/names in the placeholders (<XXX>) given above.
  • This has been tested on a demo environment.

Link to Github Gist: HERE

amazon web services aws awscli cloud iam rds mysql