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:
- MySQL 8.0, minor version 8.0.16 or higher
- MySQL 5.7, minor version 5.7.16 or higher
- MySQL 5.6, minor version 5.6.34 or higher
- PostgreSQL 13, all minor versions
- PostgreSQL 12, all minor versions
- PostgreSQL 11, all minor versions
- PostgreSQL 10, minor version 10.6 or higher
- PostgreSQL 9.6, minor version 9.6.11 or higher
- PostgreSQL 9.5, minor version 9.5.15 or higher
- All DB instance classes are supported, except for
db.t2.small
anddb.m1.small
. - IAM database authentication is not supported for MySQL 5.5.
Enabling IAM Auth for RDS
Alright, so if this is sorted, we can continue with the below steps:
Enable IAM Authentication in existing RDS using the link here: Enabling and Disabling IAM Database Authentication
Login to RDS with master username password.
1
mysql -h <RDS_ENDPOINT> --user <MASTER_USERNAME> --password
Create Users with specific database access using the below commands:
1
2mysql> CREATE USER <USERNAME> IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
mysql> grant all privileges on <DATABASE_NAME>.* to <USERNAME> IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';Get the DB Identifier for IAM policy generation:
1
DB_ID="$(aws rds describe-db-instances --query 'DBInstances[?DBInstanceIdentifier==`<RDS_NAME>`].DbiResourceId' --output text)"
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>"
]
}
]
}Use the below script to connect to the RDS:
1
2
3
4
5
6
7
8
9
10
# 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 toDB_ID1
USERNAME2
can have full admin access to entireDB_ID2
USERNAME3
can have admin access toDB_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