【问题标题】:Parsing SNS with Nodejs via Lambda通过 Lambda 使用 Nodejs 解析 SNS
【发布时间】:2019-01-25 21:39:07
【问题描述】:

我正在尝试解析由 CloudFormation 触发的 SNS 消息,然后将变量传递给获取堆栈详细信息的函数,并将它们发送到其他 SNS 主题

创建 Cloudformation 堆栈时,会发送多个 SNS 消息。我已经成功地为堆栈的“Create_Complete”通知解析了我的代码的exports.handler 片段。从那里,它解析消息的其余部分并创建几个变量,我试图将它们传递给我的 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 函数中的变量工作正常。

【问题讨论】:

  • 你得到什么错误?什么不起作用?

标签: node.js aws-lambda


【解决方案1】:

注意:我假设您使用 Node 8 作为运行时,因为您的处理函数签名中没有回调。

查看您的代码,它似乎没有考虑到 Javascript 是异步的,因此处理程序完成而不希望 list_stack_resources() 完成。

我的解决方案(使用 Node 8 和 async/await):

  1. 您的函数应该返回一个 Promise。
    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;
    };
  1. 使用异步/等待。
    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);
        }
    }

【讨论】:

    猜你喜欢
    • 2017-04-18
    • 2021-05-26
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 2019-02-11
    • 2018-04-10
    相关资源
    最近更新 更多