解密多个环境。 AWS Lambda中的变量

时间:2017-06-27 19:58:34

标签: node.js amazon-web-services

我需要在AWS Lambda函数中解密许多加密的环境变量。他们提供了一些示例代码,但我不想为我需要解密的每个值运行一个巨大的块:

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);
        });
    }
};

我想知道AWS SDK是否包含允许我一次解密多个值的功能。如果不这样做,有没有办法优雅地将这些调用链接在一起,这样他们就不会占用我这个简单功能的约75行呢?

2 个答案:

答案 0 :(得分:12)

您可以使用promises来实现这一目标。请参阅下面的示例,以通过KMS解密用户名和密码。您可以为decryptPromises数组添加尽可能多的其他解密承诺:


    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);
            });
        }
    };

您可以在Support for Promises in the SDK文档中找到有关AWS SDK如何实现承诺的更多信息。

答案 1 :(得分:0)

我创建了一个类来解密Amazon Lambda中的变量。它使用异步等待而不是Promises.all。您不需要导入lodash库。您可以修改波纹管类以使其不使用(改为使用forEach)。

var _ = require('lodash/core');
const AWS = require('aws-sdk');
class EnvVarsDecryptor {
  constructor(encryptedVariables) {
    this.encryptedVariables = encryptedVariables;
    this.decrypted = {};
  }
  isDecrypted() {
    return _.every(this.encryptedVariables, (e) => this.decrypted[e] != undefined && this.decrypted[e] != null);
  }
  async decryptVars() {
    const kms = new AWS.KMS();
    try {
      for ( let index = 0; index <  this.encryptedVariables.length; index++) {
        const encrypted = this.encryptedVariables[index];
        const data = await kms.decrypt({CiphertextBlob: new Buffer(process.env[encrypted], 'base64') }).promise();
        this.decrypted[encrypted] = data.Plaintext.toString('ascii');
      }
    } catch( e) {
      console.error(e);
    }
    return this.decrypted;
  }
}
module.exports = EnvVarsDecryptor;

var _ = require('lodash/core'); const AWS = require('aws-sdk'); class EnvVarsDecryptor { constructor(encryptedVariables) { this.encryptedVariables = encryptedVariables; this.decrypted = {}; } isDecrypted() { return _.every(this.encryptedVariables, (e) => this.decrypted[e] != undefined && this.decrypted[e] != null); } async decryptVars() { const kms = new AWS.KMS(); try { for ( let index = 0; index < this.encryptedVariables.length; index++) { const encrypted = this.encryptedVariables[index]; const data = await kms.decrypt({CiphertextBlob: new Buffer(process.env[encrypted], 'base64') }).promise(); this.decrypted[encrypted] = data.Plaintext.toString('ascii'); } } catch( e) { console.error(e); } return this.decrypted; } } module.exports = EnvVarsDecryptor;

这是说明如何使用该功能的示例:

exports.handler = async (event) => {
  if (!decryptor.isDecrypted()) {
        await decryptor.decryptVars();
  }
  console.log(decryptor.decrypted);
  return `Successfully processed ${event.Records.length} messages.`;
};