Connect Lambda to RDS using IAM credentials

It is safer to connect to RDS using IAM credentials rather than database user credentials. You can assign a role to lambda with permissions to access database. In order to access database, you will need to generate token and this token will be valid for a very limited time. Thus, no need to encrypt and rotate passwords. And no need to worry about saving passwords in Vault and then manage vault access etc.
Following steps are required to connect to RDS using IAM role:
  1. Modify RDS Instance and Enable IAM Authentication for RDS Instance
  2. Create database user, without password and assign relevant privileges
  3. Create IAM Policy with permissions to connect to database
  4. Create IAM role. This role will be assigned to lambda/ec2-instance
  5. Download SSL Certificates for RDS provided by AWS. These certificates are region specific
  6. Use Java-SDK to generate token and use this token to connect to RDS  

Enable IAM Authentication

Log into AWS Management console to modify RDS instance settings. Select RDS instance, click modify, and then select ‘Enable IAM Authentication’

Create Database User

We will create database user and lambda will use this username to connect to Database. Connect to your rds instance using any client tool and execute following queries.
CREATE USER 'lambda_user' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS'; 
GRANT ALL PRIVILEGES ON test_database.* TO ' lambda_user '@'%';
FLUSH PRIVILEGES;

Create IAM Policy


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": ["rds-db:connect"],
            "Resource": ["arn:aws:rds-db:eu-west-1:<AwsAccountId>:dbuser:<DbResourceId>/<DbUserName>"]
        }
    ]
}
Replace Account Id with your AWS Account Id. You can find Db Resource id of your instance on RDS User Interface under tab Configuration. Next replace DbUserName with your database user created above.

Create IAM Role

Create IAM service role (to be used by Lambda) and assign the policy created above to this role.

Download RDS SSL Certificate

Find key of ssl certificate for your region by accessing this url. And then download certificate by accessing url: https://s3.amazonaws.com/rds-downloads/<key_of_region_specific_ssl>

Java Code

You can get the java code from AWS Forum post to connect to database. Upload this function to AWS Lambda and assign the role created in Step 3. The code is using Default Credentials Provider Chain to get credentials, which means in the absence of environment variables and credentials file, eventually credentials will be retrieved against the role assigned. In your lambda project, place already downloaded certificates in the resources folder. In Lambda function, you can read URL of resource as:
URL url = classLoader.getResource("resources/"+SSL_CERTIFICATE);
Deploy Lambda function and it should be able to connect to RDS instance.

If RDS is not publicly accessible?

Above instructions assume that RDS instance is publicly accessible. If RDS instance is not publicly accessible, then you will need following changes for your lambda function to connect to RDS.
  1. Launch Lambda in same VPC as RDS instance
  2. Assign Security group to lambda, security group should allow outbound traffic at 3306
  3. Change security group of RDS such that it allows traffic from security group of Lambda
References:
  1. AWS Forum Post

Comments

Popular posts from this blog

Practice Questions - AWS Solutions Architect - Associate Certification

Continuous Integration using AWS CodePipeline (GitHub to Elastic BeanStalk)

AWS Parameter Store