我需要在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行呢?
答案 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.`;
};