Connecting to RDS using IAM user

Francisco Edilton
3 min readDec 13, 2017

Existe uma versão em português para esse artigo. Clique aqui.

In general, I don't like to put credentials inside files or apps, because the rotation of them drive me nuts. It usually wastes precious time during changes, new deployments etc.

So, when I saw this blog post releasing the feature, which provides the option to connect to a RDS instance (Mysql and Aurora) using IAM credentials, I thought that this will save me a lot of time. One of the main reasons is the fact that the keys are rotated every 15 minutes. Yeah! No compliance issues anymore.

But there is one drawback, managing the keys, AWS using STS (Security Token Service), your app must support it to call and generate the token. I'll show some samples below.

There is an official link that you really should check for updates. But right now, you must be running the following versions of databases (inside RDS, of course) to be able to use IAM credentials:

  • Mysql 5.6: 5.6.34 or higher
  • Mysql 5.7: 5.7.16 or higer
  • Aurora 1.10 or higher

IMPORTANT: your RDS instance must have the option IAM DB Authentication enabled. If it isn't, you must modify your instance. Don't worry there is no downtime and just a reminder, you MUST use SSL option on your connection.

For this post the Mysql 5.7.17 was used inside a t2.micro instance in Ohio (us-east-2).

First we need to define the username. For this post I picked “usuarioiam”.

Let’s connect to DB and create this user. You should use the following command:

create user usuarioiam IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';

Now, we need to create a IAM policy. Save it with a friendly name, as you need to remember it later.

IMPORTANT: this ARN is a little bit different from the standard one. It has the following pattern:

arn:aws:rds-db:region:account-id:dbuser:dbi-resource-id/database-user-name

You can find the Resource ID of your RDS at the AWS Console or CLI. It looks like this:

db-KKKABAAABBBCCCDDD222111ZZZ

Next step, create an IAM EC2 role with the above policy attached and save it, friendly name again.

INFORMATION: You can create a user as well, but the idea is to avoid put credentials inside the instance.

Attach the role to your instance and let's do some tests.

You can connect using the info from AWS or following the samples below:

Bash

First configure your AWS CLI, you don't need to put the Access Key and Secret key, leave them blank:

aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: us-east-2
Default output format [None]: json

Now ask for the token:

aws rds generate-db-auth-token --hostname endpoint_rds --port 3306 --username usuarioiam

You should get something like this:

endpoint.us-east-2.rds.amazonaws.com:3306/?Action=connect&DBUser=usuarioiam&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Date=20170917T121427Z&X-Amz-SignedHeaders=host&X-Amz-Security-Token=FQoAYXdzEHUaDMlp%2BntuaLCNDgveTCK3Aw90z3NVoCj77hdHTdZioE22dcvamgE1PTKqjfcRXjMiJptfK809%2F8NdzZwq1K1sDzBtfTwRfhmmwHvZHbgiKy5VPeXXsSmL%2BUZ7v35oGdVHDHUQFBNE9VlcRgJ6xPN5NNIr4wfDPY4miIAicedopydmu9nfZykrepIqvkV1R8xmvqVdLc8OHDbGAPwtcNlip0I6qcWztTd9Zr7HedEUrh%2B6is1xKKu6T2HrZmeE4%2BDzxSB3YIaNRo8WlWqv2yg2ta3%2FM8BMQ2UP%2BDxVSLljGqVDOPBTfzKSwK4y5it3jKjlYHPACzBo0Abd1xH5w5zxvIKeatwzCpwCQbyhg0pgY0ZNWeEMavMTjiB6NdH4jqEihsINGO5AwRjBuiyRDyhEGEMUpKlr6fiXIG9UPRxDdGwcisAUDOhWXH5yDTZws8m%2FguB4WTqYW6GpMKn0MK7qzGp1o1bvQRHOyASybEXVoKBYLwbz%2BaE3JGpcDHINJmUXtAPzgRQGTLaFD1Er0QZUWQjohKYMIn9Ua8GSyoLGpOY%2BEj%2BQLzUK1XtE3%2B%2FVtXN21q0w9why%AAAe4F9jUESoyCGY55KuSbCko4cv5zQU%3D&X-Amz-Credential=AAAAINTO6669S111MIKA%2F20170917%2Fus-east-2%2Frds-db%2Faws4_request&X-Amz-Signature=87bcd57ffeae4b825e3ff9309bea27cf8ce06baef2d77d8b2561ebcb7fc4f186

The token contains everything needed, so you have to copy it entirely. Run the command below replacing the word PASS for your token.

mysql -h endpoint.rds.amazonaws.com -u usuarioiam --ssl --enable-cleartext-plugin --password='PASS'

We are in. Obviously the user has no grant options, so will not be allowed to do such a thing. But it works!

Python

Download the CA from RDS, if you need any other info or more keys, use this link:

Code for token generation and connection:

Java

This code was copied from RDS docs

Token generation:

DB connection:

I really hope this post helps you. But if you have any question, please let me know by commenting below and if you are just testing don't forget to remove the AWS resources.

--

--