Обновление:
После долгих испытаний и испытаний я определил, что код ниже [runtime узла nodejs8.1], который является базовой установкой CodePipeline без дополнительного кода, работает нормально, когда каждый вызывает Lambda нормально, но если он пытается вызвать Lambda изнутри VPC, codepipeline.putJobSuccessResult()
зависает и Lambda истекает. Любой код, который приходит перед вызовом, работает нормально, но он просто не будет запускаться codepipeline.putJobSuccessResult()
и возвращать CodePipeline правильное возвращаемое значение, несмотря на то, что и codepipeline, и Lambda играют роль, которая имеет все виды политик и доверительных отношений, а также VPC имеет множество конечных точек, а также шлюз NAT и интернет-шлюз. Это приводит к тому, что CodePipeline постоянно повторяет попытки до истечения времени ожидания (~ 15 минут).
Обратите внимание, что до добавления лямбда-кода в CodePipeline и добавления конечной точки, когда я вручную запускал лямбда и успешно использовал статический IP-адрес через NAT => Интернет-шлюз (https://medium.com/@matthewleak/aws-lambda-functions-with-a-static-ip-89a3ada0b471) и снова, даже внутри CodePipeline, Lambda работает нормально, пока не использует функции AWS SDK aws.CodePipeline.putJobSuccessResult()
/ aws.CodePipeline.putJobFailureResult()
, весь другой код успешно выполняется.
Теоретически для воспроизведения достаточно взять приведенный ниже код и создать Lambda, настроить VPC, как описано в статье выше, настроить базовый CodePipeline и вызвать Lambda как часть конвейера. Первый прогон должен работать нормально. Затем назначьте Lambda на VPC и подсети, затем снова запустите конвейер и посмотрите, не зависает ли он при попытке поставить JobSuccessResult.
Повисшее поведение подразумевает, что это проблема с сетью, но если CodePipeline имеет конечную точку для VPC и может успешно вызывать Lambda, почему Lambda не сможет общаться с CodePipeline для putJobSuccessResult / putJobFailureResult? Я предполагаю, что либо я что-то упускаю с точки зрения VPC, либо CodePipeline работает неправильно и / или неправильно использует свою конечную точку - но я бы хотел это выяснить.
// 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');
}