0

I'm following this solution: how do I use aws secret manager with nodejs lambda

I can retrieve the secret following this solution but having problem when I try using this secret to connect to mysql db

Here the code to get secret manager value

async function getSecret(secretName) {
    // Load the AWS SDK
    var AWS = require('aws-sdk'),
        region = process.env.REGION,
        secretName = secretName,
        secret,
        decodedBinarySecret;

    // Create a Secrets Manager client
    var client = new AWS.SecretsManager({
        region: region
    });

    return new Promise((resolve,reject)=>{
        client.getSecretValue({SecretId: secretName}, function(err, data) {

            // In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
            // See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
            // We rethrow the exception by default.
            if (err) {
                reject(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) {
                    resolve(data.SecretString);
                } else {
                    let buff = Buffer.from(data.SecretBinary, 'base64');
                    resolve(buff.toString('ascii'));
                }
            }
        });
    });
}

module.exports = {
    getSecret
}

And here where I retrieve the secret value and assigned it to my db config

const mysql = require('mysql2/promise');
const SecretsManager = require('./secret')

async function connect() {
    // set and get secret manager
    const secretName = process.env.SECRET_NAME
    const secret_value = await SecretsManager.getSecret(secretName);

    try {
        // set db config
        const config = {
                host: process.env.DB_HOST,
                port: '3306',
                user: secret_value.username,
                password: secret_value.password,
                database: process.env.DB_NAME
            }
        console.log(config)
        const connection = await mysql.createConnection(config);
        return connection
        
        
    } catch (err) {
        console.log(`MySQL connection error: ${err}`)
    }

}

module.exports = {
    connect
}

So when I console.log the value of secret_value, I can see all the secret info in there, but not when I'm console.log config. I will get undefined on user and password value

{
  host: 'xxxx',
  port: '3306',
  user: undefined,
  password: undefined,
  database: 'xxx'
}

this mysql connection function was call from the index file

const mysql_connect = require('./services/connection')
exports.handler = async (event, context) => {
  try{
        // connect db
        const connection = await mysql_connect.connect()
  } catch(err) {
        console.log(err)
  }
}
  • You need to `JSON.parse the SecretString` to an object as specified [in this answer](https://stackoverflow.com/a/66998570/5189811) in order to perform field access on it. – Oluwafemi Sule Nov 09 '22 at 10:16
  • I dont understand. I need to JSON.parse the secret_value or JSON.parse both secret_value.username and secret_value.password @OluwafemiSule – Zalizan Zolkipali Nov 09 '22 at 10:24
  • You need to decode the secret string resolved when invoking `SecretsManager.getSecret` in the `connect` function. Something along these lines: `let secret_value = await SecretsManager.getSecret(secretName); secret_value = JSON.parse(secret_value);` – Oluwafemi Sule Nov 09 '22 at 10:27

1 Answers1

0

EDIT: Solve this by using suggestion from brother @OluwafemiSule in the comment. Here my latest connection code in my connection

const mysql = require('mysql2/promise');
const SecretsManager = require('./secret')

async function connect() {
    // set and get secret manager
    const secretName = process.env.SECRET_NAME
    const region = process.env.REGION
    let secret_value = await SecretsManager.getSecret(secretName, region);
    secret_value = JSON.parse(secret_value)

    try {
        // set db config
        const config = {
            host: process.env.DB_HOST,
            port: '3306',
            user: secret_value.username,
            password: secret_value.password,
            database: process.env.DB_NAME
        }
        console.log(config)
        const connection = await mysql.createConnection(config);
        return connection

    } catch (err) {
        console.log(`MySQL connection error: ${err}`)
    }

}

module.exports = {
    connect
}