Разбор SNS с Nodejs через Lambda - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь проанализировать сообщение SNS, инициированное CloudFormation, а затем передать переменные в функцию, которая получает сведения о стеке и отправляет их в другой раздел SNS

При создании стека Cloudformation,отправлено несколько сообщений SNS.Я успешно получил часть моего синтаксического анализа export.handler для уведомления "Create_Complete" для стека.Оттуда он анализирует остальную часть сообщения и создает пару переменных, которые я пытаюсь передать моей функции list_stack_resources, которую я хотел бы использовать, чтобы получить подробную информацию о ресурсах, созданных стеком, а затем отправить эти данные.на другую тему SNS, на которую я подпишусь.

Вот пример уведомления SNS

StackId='arn:aws:cloudformation:us-west-2:999999999999:stack/SNS-TEST/9999999-999-9999-9999-99999999999'
Timestamp='2019-01-15T21:27:09.503Z'
EventId='50aba940-190c-11e9-982b-0af0c7a25b8e'
LogicalResourceId='SNS-TEST'
Namespace='652493332725'
PhysicalResourceId='arn:aws:cloudformation:us-west-2:999999999999:stack/SNS-TEST/9999999-999-9999-9999-99999999999'
PrincipalId='652493332725'
ResourceProperties='null'
ResourceStatus='CREATE_COMPLETE'
ResourceStatusReason=''
ResourceType='AWS::CloudFormation::Stack'
StackName='SNS-TEST'
ClientRequestToken='Console-CreateStack-9999999-9999-9999-9999-999999999999'

Вот код js моего узла:

    topic_arn = "arn:aws:sns:us-west-2:652493332725:AB-Lambda-To-SNS";
    var AWS = require('aws-sdk'); 
    AWS.config.region_array = topic_arn.split(':'); // splits the ARN in to and array 
    AWS.config.region = AWS.config.region_array[3];  // makes the 4th variable in the array (will always be the region)

    // ####################   BEGIN LOGGING   ########################
    console.log(topic_arn);   // just for logging to the that the var was parsed correctly
    console.log(AWS.config.region_array); // to see if the SPLIT command worked
    console.log(AWS.config.region_array[3]); // to see if it got the region correctly
    console.log(AWS.config.region); // to confirm that it set the AWS.config.region to the correct region from the ARN
    // ####################  END LOGGING (you can remove this logging section)  ########################

    // Searches SNS messages for stack creation complete notification, parses values to create variables for StackId and LogicalResourceId
    exports.handler = function(event, context) {
        const message = event.Records[0].Sns.Message;
        if ((message.indexOf("ResourceStatus='CREATE_COMPLETE'") > -1) && (message.indexOf("ResourceType='AWS::CloudFormation::Stack'") > -1)) {
            var fields = message.split("\n");
            subject = fields[11].replace(/['']+/g, '');
            stack_id = fields[11].replace(/['']+|StackName=/g, '');        
            logical_resource_id = fields[3].replace(/['']+|LogicalResourceId=/g, '');        
            list_stack_resources(stack_id);
        }
    };

    // describes resources created by the stack and publishes results to the send_SNS_notification function
    function list_stack_resources(stack_id) {
        var cloudformation = new AWS.CloudFormation();
        cloudformation.listStackResources({
                StackName: stack_id,
        },  function(err, data) {
            if (err) console.log(err, err.stack); // an error occurred
            else     resources = data;           // successful response
            send_SNS_notification(resources);        
            });
        }

function send_SNS_notification(resources) {
    var sns = new AWS.SNS();
    sns.publish({ 
        Subject: "subject",
        Message: resources,
        TopicArn: topic_arn
    }, function(err, data) {
        if (err) {
            console.log(err.stack);
            return;
        } 
        console.log('push sent');
        console.log(data);
    });
}

Я не верю, что переменные в функции list_stack_resources работают правильно.

1 Ответ

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

Примечание: я предполагаю, что вы используете Node 8 в качестве среды выполнения, поскольку у вас нет обратного вызова в сигнатуре функции обработчика.

Если посмотреть на ваш код, он выглядит следующим образомон не учитывает, что Javascript является асинхронным, поэтому обработчик завершает работу, не ожидая завершения list_stack_resources().

Мое решение (с использованием Node 8 и async / await):

  1. Ваша функция должна вернуть Обещание.
    exports.handler = function (event, context) {
        const message = event.Records[0].Sns.Message;
        if ((message.indexOf("ResourceStatus='CREATE_COMPLETE'") > -1) && (message.indexOf("ResourceType='AWS::CloudFormation::Stack'") > -1)) {
            var fields = message.split("\n");
            subject = fields[11].replace(/['']+/g, '');
            stack_id = fields[11].replace(/['']+|StackName=/g, '');
            logical_resource_id = fields[3].replace(/['']+|LogicalResourceId=/g, '');

            return list_stack_resources(stack_id);
        }

        // Up to you to decide the return value but all code branches should return.
        return true;
    };
Использовать async / await.
    async function list_stack_resources(stack_id) {
        const cloudformation = new AWS.CloudFormation();

        try {
            const resources = await cloudformation.listStackResources({
                StackName: stack_id,
            }).promise();

            return send_SNS_notification(resources);
        } catch(err) {
            console.log(err, err.stack);
        }
    }

    async function send_SNS_notification(resources) {
        const sns = new AWS.SNS();

        try {
            const data = await sns.publish({
                Subject: "subject",
                Message: resources,
                TopicArn: topic_arn
            }).promise();

            console.log('push sent');
            console.log(data);
        } catch (err) {
            console.log(err.stack);
        }
    }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...