从VPC调用Lambda时,codepipeline.putJobSuccessResult()挂起

时间:2019-01-15 00:10:19

标签: amazon-web-services aws-lambda aws-codepipeline

更新: 经过大量的试验和磨难,我确定[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

2 个答案:

答案 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”错误(这种愚蠢的错误实在是太痛苦了),但我认为在关联路由表的用户体验方面还有待改进。