更新:
经过大量的试验和磨难,我确定[nodejs8.1 runtime]下面的代码(它是基本的CodePipeline设置,没有其他代码)在正常调用Lambda时可以正常工作,但是如果尝试从内部调用Lambda VPC,codepipeline.putJobSuccessResult()
挂起,Lambda超时。调用之前出现的所有代码都可以正常运行,但即使代码管道和Lambda都具有各种策略和信任关系,并且不会运行codepipeline.putJobSuccessResult()
并且不会给aws.CodePipeline.putJobSuccessResult()
提供适当的返回值给CodePipeline,并且VPC有很多端点以及NAT网关和Internet网关。这导致CodePipeline不断重试直到超时时间(〜15分钟)。
还请注意,在将Lambda添加到CodePipeline并添加手动运行Lambda并通过NAT => Internet Gateway(https://medium.com/@matthewleak/aws-lambda-functions-with-a-static-ip-89a3ada0b471)成功使用静态IP的端点之前,甚至在在使用CodePipeline之前,Lambda可以正常运行,直到它利用AWS SDK aws.CodePipeline.putJobFailureResult()
/ // Working Base response code for CodePipeline
'use strict';
const aws = require('aws-sdk');
const codepipeline = new aws.CodePipeline();
let environment = 'dev';
let callback;
let context = {
invokeid: ''
}
exports.handler = async (event, context, callback) => {
context = context;
callback = callback;
console.log('Inside deploy-website Lambda');
if (!('CodePipeline.job' in event)) {
return Promise.resolve();
}
// Retrieve the Job ID from the Lambda action
let jobId;
if (event["CodePipeline.job"]) {
jobId = event["CodePipeline.job"].id;
// Retrieve the value of UserParameters from the Lambda action configuration in AWS CodePipeline, in this case the environment
// to deploy to from this function
environment = event["CodePipeline.job"].data.actionConfiguration.configuration.UserParameters || environment;
}
console.log(`Envrionment: ${environment}`);
console.log('Copy Successful');
console.log('Entering Results');
return await putJobSuccess('Copy Successful', jobId);
}
// Notify AWS CodePipeline of a successful job
async function putJobSuccess(message, jobId) {
console.log(`Post Job Success For JobID: ${jobId}`);
const params = {
jobId: jobId
};
console.log(`Job Success Params: ${JSON.stringify(params)}`);
await codepipeline.putJobSuccessResult(params).promise();
console.log('Job Success: Successfully reported hook results');
return callback(null, 'Job Success: Successfully reported hook results');
}
函数为止;其他所有代码均已成功执行。
从理论上讲,要重现,只需执行以下代码并创建Lambda,按照上述文章中的说明设置VPC,设置基本的CodePipeline并将Lambda作为管道的一部分进行调用。第一次运行应该正常。然后将Lambda分配给VPC和子网,然后再次运行管道,并在尝试putJobSuccessResult时查看它是否未挂起。
挂起行为表示这是一个网络问题,但是如果CodePipeline具有VPC的终结点并能够成功调用Lambda,为什么Lambda无法与CodePipeline对话以放置putJobSuccessResult / putJobFailureResult?我的猜测是,我丢失了某些VPC或CodePipeline无法正常工作和/或正确使用了其端点-但我想弄清楚。
library(dplyr)
library(lubridate)
df %>%
group_by(Date = as.Date(datetime)) %>%
mutate(F_mean = mean(F[hour(datetime) == 0]),
value = (F_mean - F)/F_mean) %>%
ungroup() %>%
select(-F_mean, -Date)
# datetime F value
# <dttm> <dbl> <dbl>
# 1 2012-01-01 00:00:00 1.97 -0.902
# 2 2012-01-01 00:01:00 0.194 0.813
# 3 2012-01-01 00:02:00 1.52 -0.467
# 4 2012-01-01 00:03:00 1.66 -0.599
# 5 2012-01-01 00:04:00 0.765 0.262
# 6 2012-01-01 00:05:00 1.31 -0.267
# 7 2012-01-01 00:06:00 1.62 -0.565
# 8 2012-01-01 00:07:00 0.642 0.380
# 9 2012-01-01 00:08:00 1.62 -0.560
#10 2012-01-01 00:09:00 1.68 -0.621
# ... with 44,631 more rows
答案 0 :(得分:0)
使用Lambda的Node 6/8运行时,如果您使用Promises(甚至使用async/await
语法),会更容易。
旧的context.succeed()
/ context.fail()
语法适用于旧的Node版本,并且已弃用。
// Leave this outside your handler so you don't instantiate in every invocation.
const codepipeline = new aws.CodePipeline();
exports.handler = event => {
if (!('CodePipeline.job' in event)) {
return Promise.resolve();
}
const jobId = event['CodePipeline.job'].id;
const environment = event['CodePipeline.job'].data.actionConfiguration.configuration.UserParameters;
return doStuff
.then(() => putJobSuccess(message, jobId));
}
function putJobSuccess(message, jobId) {
console.log('Post Job Success For JobID: '.concat(jobId));
const params = {
jobId: jobId
};
return codepipeline.putJobSuccessResult(params).promise()
.then(() => {
console.log(`Post Job Success Succeeded Message: ${message}`);
return message;
})
.catch((err) => {
console.log(`Post Job Failure Message: ${message}`);
throw err;
});
}
答案 1 :(得分:0)
事实证明,这确实是一个网络问题。似乎VPC路由表正是我的所在。创建路由表时,可以选择一个名称和一个与其关联的VPC。我忘了要做的是进入子网并将其关联到“路由表”选项卡下的正确路由表,和/或我没有在其中一个上选择正确的路由表,因为当您选择路由表进行关联时到,它不显示逻辑名称,而仅显示路由表ID,这更容易出错。因此,尽管这绝对是“ Newb”错误(这种愚蠢的错误实在是太痛苦了),但我认为在关联路由表的用户体验方面还有待改进。