- Lab
- A Cloud Guru
Using Secrets Manager to Authenticate with an RDS Database Using Lambda
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.
Path Info
Table of Contents
-
Challenge
Create a Lambda Function
Create a Lambda function using Node.js version18.x. Join it to the provided VPC and the 2 public subnets, and use the lab-provided security group DatabaseSecurityGroup. Name your function
testRDS
. Update the function timeout setting to 6 seconds. -
Challenge
Create the MySQL Layer, and Copy Your Code to the Lambda Function
- Create a new layer called
mysql
and selectNode.js 18.x
. Upload the file MySQL Library Zip file, - Add the mysql layer to your
testRDS
function as a custom layer.
- Create a new layer called
-
Challenge
Create a Secret in Secrets Manager
- Use the Secrets Manager console to create a secret (username =
username
, initial password =password
), and enable automatic credential rotation to reoccur every 1 day. - Name the secret
RDScredentials
and your Lambda rotation functionrotateRDS
.
- Use the Secrets Manager console to create a secret (username =
-
Challenge
Test Connectivity from Lambda to RDS Using Credentials from AWS Secrets Manager
In the
index.mjs
, file replace the current code with the code shown below. Issue a deploy, and once deployed, issue a test. Ensure you replace the<RDS Endpoint>
placeholder with the endpoint of your RDS MySQL database.import mysql from 'mysql2/promise'; import AWS from 'aws-sdk'; const secretName = 'RDScredentials'; const region = 'us-east-1'; const rdsEndpoint = '<RDS Endpoint>'; const databaseName = 'example'; AWS.config.update({ region: region }); const secretsManager = new AWS.SecretsManager(); export const handler = async (event, context) => { try { const data = await secretsManager.getSecretValue({ SecretId: secretName }).promise(); const secret = JSON.parse(data.SecretString || Buffer.from(data.SecretBinary, 'base64').toString('ascii')); const { username, password } = secret; const connection = await mysql.createConnection({ host: rdsEndpoint, user: username, password: password, database: databaseName, }); const [rows] = await connection.execute('SHOW TABLES'); console.log('Tables:'); rows.forEach((row) => { console.log(row[`Tables_in_${databaseName}`]); }); connection.end(); return { statusCode: 200, body: 'Tables listed successfully', }; } catch (err) { console.error('Error:', err.message); return { statusCode: 500, body: 'Error listing tables', }; } };
-
Challenge
Create Table in the RDS Database Using Lambda to Check Connectivity
Copy and paste the following code in your index.mjs tab, replacing the
<RDS Endpoint>
placeholder with your own RDS endpoint. This code adds a table into the example database calledpets
. We will use this table as a reference to ensure successful database communication:import mysql from 'mysql2/promise'; export const handler = async (event, context, callback) => { try { const connection = await mysql.createConnection({ host: "<RDS Endpoint>", user: "username", password: "password", database: "example", }); // Create 'pets' table await connection.execute(` CREATE TABLE IF NOT EXISTS pets ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, age INT NOT NULL ) `); console.log('Table created: pets'); // List all tables const [rows] = await connection.execute('SHOW TABLES'); console.log('Tables:'); rows.forEach((row) => { console.log(row[`Tables_in_example`]); }); connection.end(); callback(null, { statusCode: 200, body: 'Tables listed successfully', }); } catch (err) { console.error(err); callback(err, { statusCode: 500, body: 'Error listing tables', }); } };
-
Challenge
Modify the Lambda IAM Role
The IAM role created for Lambda to use does not have permission to the Secrets Manager service. Edit the Lambda execution role that was created and add the following AWS managed policy:
SecretsManagerReadWrite
.
What's a lab?
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.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.