Rod
Rod

Reputation: 15475

AWS Lambda: Sequelize acess denied error after accessing successfully the first time

I have an AWS Lambda that uses Sequelize ORM to talk to AWS Aurora. It works fine the first time it's accessed but then after some unknown amount of minutes the Lambda errors out with a Sequelize error saying access denied for [email protected]

async function connect() {
    const signer = new AWS.RDS.Signer({
        'region': region,
        'username': dbUsername,
        'hostname': dbEndpoint,
        'port': dbPort
    });

    let token;
    await signer.getAuthToken((error, result) => {
        if (error) {
            throw error;
        }

        token = result;
    });

    return token;
};

const sequelizeOptions = {
    'host': dbEndpoint,
    'port': dbPort,
    'ssl': true,
    'dialect': 'mysql',
    'dialectOptions': {
        'ssl': 'Amazon RDS',
        'authSwitchHandler': (data, callback) => {
            if (data.pluginName === 'mysql_clear_password') {
                const password = token + '\0';
                const buffer = Buffer.from(password);
                callback(null, buffer);
            }
        }
    },
    pool: {
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000
    }
};

let token;

exports.create = async () => {
    token = await connect();
    return new Sequelize(dbName, dbUsername, token, sequelizeOptions);
}

exports.buildResponse = resultsArray => {
    return {
        "statusCode": 200,
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Credentials": true
        },
        "body": JSON.stringify(resultsArray),

        "isBase64Encoded": false
    };
};

reference: article

Upvotes: 0

Views: 681

Answers (1)

K Mo
K Mo

Reputation: 2155

Posting as a more explicit answer than my previous comment.

Short answer

As you are reusing a token and db connection created outside of the lambda handler, one or both of those things is timing out.

Longer answer

Lambdas run in containers, those containers will be re-used until killed due to inactivity or code change, but once a container is running only the code inside of the handler function is run on subsequent invocations.

This means that code run outside of a handler function is only run when a new container is started (because there is no running container or a concurrent invocation is received).

If code outside of the handler creates something that is time limited, like creating a db connection or receiving a time limited token, and the lambda is invoked often enough not to kill the container, time will simply run out.

Upvotes: 1

Related Questions