Using Secrets Manager to Authenticate with an RDS Database Using Lambda

1 hour
  • 4 Learning Objectives

About this Hands-on Lab

AWS Secrets Manager helps you protect secrets needed to access your applications, services, and IT resources. The service enables you to easily rotate, manage, and retrieve database credentials, API keys, and other secrets throughout their lifecycle. In this lab, we connect to a MySQL RDS database from an AWS Lambda function using a username and password, and then we hand over credential management to the AWS Secrets Manager service. We then use the Secrets Manager API to connect to the database instead of hard-coding credentials in our Lambda function. By the end of this lab, you will understand how to store a secret in AWS Secrets Manager and access it from a Lambda function.

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Create a Lambda Function

Create a Lambda function and join it to the provided VPC and the 2 public subnets. Name your function testRDS. Update the function timeout setting to 6 seconds.

Create the MySQL Layer, and Copy Your Code to the Lambda Function
  1. Create a custom mysql layer for Node.js 14.x, using the MySQL Library Zip file, and add it to your testRDS function.

  2. Copy and paste the following code in your index.js tab, replacing the <RDS Endpoint> placeholder with your own RDS endpoint:

    var mysql = require('mysql');
    
    exports.handler = (event, context, callback) => {
    
        var connection = mysql.createConnection({
            host: "<RDS Endpoint>",
            user: "username",
            password: "password",
            database: "example",
        });
    
        connection.query('show tables', function (error, results, fields) {
            if (error) {
                connection.destroy();
                throw error;
            } else {
                // connected!
                console.log("Query result:");
                console.log(results);
                callback(error, results);
                connection.end(function (err) { callback(err, results);});
            }
        });
    };
  3. Deploy and test your code.

  4. Go back to your index.js tab and replace the connection.query line with the following string:

    connection.query('CREATE TABLE pet (name VARCHAR(20), species VARCHAR(20))',function (error, results, fields) {
  5. Deploy and test your code.

  6. Go back to your index.js tab, undo the code change (Ctrl+Z or Cmd+Z) to get it back to the original code you pasted in, and deploy and test your code again.

Create a Secret in Secrets Manager
  1. Use the Secrets Manager console to create a secret (User name = username, initial password = password) and enable automatic credential rotation. Name the secret RDScredentials and your rotation function rotateRDS.
  2. Update index.js using the following code, replacing the <RDS Endpoint> placeholder with your own RDS endpoint:

    var mysql = require('mysql');
    
    var AWS = require('aws-sdk'),
        region = "us-east-1",
        secretName = "RDScredentials",
        secret,
        decodedBinarySecret;
    
    var client = new AWS.SecretsManager({
        region: "us-east-1"
    });
    
    exports.handler = (event, context, callback) => {
    
        client.getSecretValue({SecretId: secretName}, function(err, data) {
            if (err) {
                console.log(err);
            }
            else {
                // Decrypts secret using the associated KMS CMK.
                // Depending on whether the secret is a string or binary, one of these fields will be populated.
    
                if ('SecretString' in data) {
                    secret = data.SecretString;
                } else {
                    let buff = new Buffer(data.SecretBinary, 'base64');
                    decodedBinarySecret = buff.toString('ascii');
                }
            }
    
            var parse = JSON.parse(secret);
            var password = parse.password;
    
            var connection = mysql.createConnection({
                host: "<RDS Endpoint>",
                user: "username",
                password: password,
                database: "example",
            });
    
            connection.query('show tables', function (error, results, fields) {
                if (error) {
                    connection.destroy();
                    throw error;
                } else {
                    // connected!
                    console.log("Query result:");
                    console.log(results);
                    callback(error, results);
                    connection.end(function (err) { callback(err, results);});
                }
            });
    
        });
    };
Test New Code

Using the code provided, test the connection to the RDS database from Lambda using the Secrets Manager API to obtain the authentication credentials.

Additional Resources

Log in to the live AWS environment using the credentials provided. Use an incognito or private browser window to ensure you're using the lab account rather than your own.

Make sure you're in the N. Virginia (us-east-1) region throughout the lab.


MySQL Library Zip file

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!

Get Started
Who’s going to be learning?