我创建了一个lambda和云形成模板,该模板允许lambda访问参数存储和机密管理器。当我测试lambda时,我在export.handler函数之外具有以下功能:
function getParameterFromStore(param){
let promise = new Promise(function(resolve, reject){
console.log('++ ' + param.Path);
servmgr.getParametersByPath(param, function(err, data){
if(err){
reject(console.log('Error getting parameter: ' + err, err.stack));
} else {
resolve(data);
}
});
});
let parameterResult = promise.then(function(result){
console.log('---- result: '+ JSON.stringify(result));
return result;
});
return parameterResult;
};
servmgr
实例化为var servmgr = new AWS.SSM();
当我从export.handler函数调用此函数时,我这样做是:
myFirstParam = { Path : '/myPath/Service/servicesEndpoint'};
let endpointResult = getParameterFromStore(myFirstParam);
在lambda中,我有一个函数来检索在promise中包装的export.handler函数bt之外定义的参数。
当我运行/测试此lambda时,返回的对象始终是未定义的……我得到Parameters [],但没有值。
2019-02-20T21:42:41.340Z 2684fe88-d552-4560-a477-6761f2de6717 ++ /myPath/Service/serviceEndpoint
2019-02-20T21:42:41.452Z 2684fe88-d552-4560-a477-6761f2de6717 ---- result: {"Parameters":[]}
如何在运行时将参数值返回给lambda?
更新
基于Thales的建议/答案,我将lambda简化为:
const getParameterFromStoreAsync = (param) => {
return new Promise((resolve, reject) => {
servmgr.getParametersByPath(param, (err, data) => {
if(err){
reject(console.log('Error getting parameter: ' + err, err.stack));
}
return resolve(data);
});
});
};
exports.handler = async(event, ctx, callback) => {
console.log('INFO[lambda]: Event: [' + JSON.stringify(event, null, 2) + ']');
console.log('this is the event' + JSON.stringify(event));
sfdcEndPointParam = { Path : '/PartnerBanking/Service/SfdcEndpoint'};
let myendpoint = await getParameterFromStoreAsync(sfdcEndPointParam);
console.log('### endpoint path: ' + JSON.stringify(myendpoint));
done = ()=>{}
callback(null, done());
};
我仍然在测试中看到一个空数组:
### endpoint path: {"Parameters":[]}
我也将函数移到了回调中
exports.handler = (event,ctx, callback){
done = async()=>{
console.log('this is the event' + JSON.stringify(event));
sfdcEndPointParam = { Path : '/PartnerBanking/Service/SfdcEndpoint'};
let myendpoint = await getParameterFromStoreAsync(sfdcEndPointParam);
console.log('### endpoint path: ' + JSON.stringify(myendpoint));}
}
callback(null, done());
相同结果...空数组。还有其他尝试吗?
答案 0 :(得分:2)
这是因为您的getParameterFromStore
在执行then()
代码之前就返回了,因此parameterResult
是undefined
。如果您不想过多更改代码,我将返回您创建的Promise,如下所示:
function getParameterFromStore(param){
return new Promise(function(resolve, reject){
console.log('++ ' + param.Path);
servmgr.getParametersByPath(param, function(err, data){
if(err){
reject(console.log('Error getting parameter: ' + err, err.stack));
} else {
resolve(data);
}
});
});
};
最后,在函数的客户端上,您可以得到如下结果:
const myFirstParam = { Path : '/myPath/Service/servicesEndpoint'}
getParameterFromStore(myFirstParam).then(console.log)
但是,在NodeJS中进行编码时,我强烈建议您改用async/await,这样您就可以逃脱Promise Hell(在Promise之后更改Promise,以便“同步”实现)
使用异步/等待时,您可以将代码设计为同步。这是使用async / await以及箭头功能的示例的重构版本:
const getParameterFromStore = param => {
return new Promise((resolve, reject) => {
console.log('++ ' + param.Path);
servmgr.getParametersByPath(param, (err, data) => {
if (err) {
console.log('Error getting parameter: ' + err, err.stack)
return reject(err);
}
return resolve(data);
});
})
}
exports.handler = async (event) => {
const endpointResult = await getParameterFromStore(event.someAttributeFromTheEventThatYouWantToUse)
console.log(endpointResult)
};
EDIT :OP修复了第一个问题后,我自己创建了一个工作示例。事实证明,OP调用API的方式不正确。
这是完整的工作示例:
'use strict';
const AWS = require('aws-sdk')
AWS.config.update({
region: 'us-east-1'
})
const parameterStore = new AWS.SSM()
const getParam = param => {
return new Promise((res, rej) => {
parameterStore.getParameter({
Name: param
}, (err, data) => {
if (err) {
return rej(err)
}
return res(data)
})
})
}
module.exports.get = async (event, context) => {
const param = await getParam('MyTestParameter')
console.log(param);
return {
statusCode: 200,
body: JSON.stringify(param)
};
};
注意Name
属性,该属性必须作为对ServiceManager.getAttribute方法的API调用的一部分提供。
此属性在官方docs
中有所说明我自己运行了这个,这是CloudWatch Logs中的输出:
如您所见,该值已成功返回。
希望这会有所帮助!
答案 1 :(得分:0)
如果您的Lambda部署在VPC上,请确保已将安全组附加到该组,并且允许出站流量。它将能够自动访问参数存储。
https://aws.amazon.com/premiumsupport/knowledge-center/lambda-vpc-parameter-store/
答案 2 :(得分:0)
一个更简单的解决方案是:
const getParameterFromStore = (params) => servmgr.getParametersByPath(params).promise();
const myFirstParam = { Path : '/myPath/Service'};
getParameterFromStore(myFirstParam).then(console.log);
如您所见,SDK本身提供实用程序功能,您可以根据需要以异步或同步方式使用它。
希望有帮助。