codepipeline.putJobSuccessResult () Зависание при вызове лямбды из VPC - PullRequest
0 голосов
/ 15 января 2019

Обновление: После долгих испытаний и испытаний я определил, что код ниже [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');
}

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Оказывается, это действительно была проблема с сетью. Кажется, что таблицы маршрутизации VPC - то, что получило меня. Когда вы создаете таблицу маршрутов, вы выбираете имя и VPC, чтобы связать его с ним. То, что я забыл сделать, это перейти к подсетям и связать их с соответствующей таблицей маршрутов на вкладке «Таблица маршрутов», и / или я не выбрал правильный на одной из них, потому что, когда вы выбираете таблицу маршрутов, чтобы связать ее до, он не показывает логическое имя, только идентификатор таблицы маршрутов, что делает его более подверженным ошибкам. Так что, хотя это была определенно ошибка «новичка» [такая большая боль от такой глупой ошибки], я думаю, что есть что-то желаемое с точки зрения пользовательского опыта при сопоставлении таблиц маршрутов.

0 голосов
/ 15 января 2019

В средах выполнения 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;
        });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...