Decrypting multiple envs. variables in AWS Lambda

I have a number of encrypted environment variables that I need to decrypt into an AWS Lambda function. They provide example code, but I would rather not run a huge chunk for every value I need to decode:

const AWS = require('aws-sdk');

const encrypted = process.env['my_password'];
let decrypted;


function processEvent(event, context, callback) {
    // TODO handle the event here
}

exports.handler = (event, context, callback) => {
    if (decrypted) {
        processEvent(event, context, callback);
    } else {
        // Decrypt code should run once and variables stored outside of the function
        // handler so that these are decrypted once per container
        const kms = new AWS.KMS();
        kms.decrypt({ CiphertextBlob: new Buffer(encrypted, 'base64') }, (err, data) => {
            if (err) {
                console.log('Decrypt error:', err);
                return callback(err);
            }
            decrypted = data.Plaintext.toString('ascii');
            processEvent(event, context, callback);
        });
    }
};

      

I am wondering if the AWS SDK includes a feature that allows me to decrypt multiple values ​​at once. Otherwise, is there a way to elegantly chain these calls so that they don't take ~ 75 lines of my simple function?

+3


source to share


1 answer


You can use promises to achieve this. See the example below for decrypting both username and password via KMS. You can add as many additional promises decryption to the array decryptPromises

as you like:

    const AWS = require ('aws-sdk');

    const encrypted = {
        username: process.env.username,
        password: process.env.password
    };

    let decrypted = {};

    function processEvent (event, context, callback) {
        // do work
    }

    exports.handler = (event, context, callback) => {
        if (decrypted.username && decrypted.password) {
            processEvent (event, context, callback);
        } else {
            const kms = new AWS.KMS ();

            const decryptPromises = [
                kms.decrypt ({CiphertextBlob: new Buffer (encrypted.username, 'base64')}) .promise (),
                kms.decrypt ({CiphertextBlob: new Buffer (encrypted.password, 'base64')}) .promise ()
            ];

            Promise.all (decryptPromises) .then (data => {
                decrypted.username = data [0] .Plaintext.toString ('ascii');
                decrypted.password = data [1] .Plaintext.toString ('ascii');

                processEvent (event, context, callback);
            }). catch (err => {
                console.log ('Decrypt error:', err);
                return callback (err);
            });
        }
    };



You can find more information on how promises were implemented in the AWS SDK at Support for promises in the SDK .

+7


source







All Articles