0

我有下面的 Lambda 函数,它应该对现有的 Dynamodb 表进行更改并将它们更改为另一个 Dynamodb 表。

我故意将我尝试过的代码注释掉了,我只有两条路径,这两条路径都会在不同的地方抛出错误。

如果我在代码中包含 SharedIniFileCredentials,我会在 Cloudwatch 日志中收到以下错误:

{
    "message": "Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1",
    "errno": -2,
    "syscall": "open",
    "code": "CredentialsError",
    "path": "/home/sbx_user1051/.aws/credentials",
    "time": "2020-11-16T02:57:31.177Z",
    "originalError": {
        "message": "Could not load credentials from SharedIniFileCredentials",
        "errno": -2,
        "syscall": "open",
        "code": "CredentialsError",
        "path": "/home/sbx_user1051/.aws/credentials",
        "time": "2020-11-16T02:57:31.177Z",
        "originalError": {
            "errno": -2,
            "syscall": "open",
            "code": "ENOENT",
            "path": "/home/sbx_user1051/.aws/credentials",
            "message": "ENOENT: no such file or directory, open '/home/sbx_user1051/.aws/credentials'"
        }
    }
}

如果我删除它并让我创建和附加的角色(AWS 文档说这是我需要做的全部)完成权限工作,我在 Cloudwatch 日志中没有错误,但我在控制台语句中看到 putItem (或者如果我使用其他类)永远不会被执行。代码在执行这些函数之前返回。因此,如果我转到 AWS 控制台并查看我的 Dynamodb 表上的 Trigger 选项卡,我会看到“问题:函数调用失败”。

我添加了环境变量。我已将密钥/秘密硬编码到代码中。我尝试使用 AWS CLI 在命令行上运行它。我添加了环境变量。我已确保正确填充了我的凭据和配置文件。无论我做什么,同样的两个问题。

我什至尝试过 AWS CLI。如果我使用以下命令在命令行上运行它

aws lambda invoke  --function-name myfunction --cli-binary-format raw-in-base64-out --payload file://mynewitem2.json output.txt

I get this after a few seconds go by

读取端点 URL 超时:“https://lambda.us-east-2.amazonaws.com/2015-03-31/functions/myfunction/invocations”

如果我添加配置文件语句,然后在命令行上重新运行它,我会得到这个,但是 Cloudwatch 日志没有显示我到达了 putItem 或 put 命令:

{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

Does anyone have any suggestions here? I have looked through all the similar requests for help with no luck. I've looked at the AWS documentation over and over. 

I'm completely stuck here. I must be missing something. I just don't know what it is. Do any of you??

Here is the Lambda function:
'use strict';
console.log("starting myplugin insertion . . . ");
var AWS = require("aws-sdk");
AWS.config.logger = console;

//AWS.config = new AWS.Config();
//AWS.config.accessKeyId = "...";
//AWS.config.secretAccessKey = "...";
//AWS.config.region = 'us-east-2';

//AWS.config.update({
      //  aws_access_key_id : '...',
      //  aws_secret_access_key : '...',
       // region: 'us-east-2'
//    });
var creds = new AWS.SharedIniFileCredentials({profile: 'myprofile'});
console.log('Creds problem: ', JSON.stringify(creds, null, 2));
AWS.config.credentials = creds;

AWS.config.getCredentials(function(err) {
 if (err) 
    console.log('Cred problem: ', JSON.stringify(err, null, 2));
  else {
    console.log("Cred Access:", JSON.stringify(AWS.config.credentials, null, 2));
  }
});

var ddb = new AWS.DynamoDB({
   'apiVersion': '2012-08-10'
});

exports.handler = (event, context, callback) => {

    console.log(JSON.stringify(event, null, 2));

    event.Records.forEach((record) => {
        console.log('my  Stream record: ', JSON.stringify(record, null, 2));
        

        if (record.eventName == 'INSERT') {
           console.log('my  INSERTING RECORD');
           
    
            var params = {
            TableName: 'myplugin_temp',
            Item: {
                    "client" : record.dynamodb.NewImage.client,
                    "expiration" : record.dynamodb.NewImage.expiration,
                    "notificationurl" : record.dynamodb.NewImage.notificationurl,
                    "clientid" : record.dynamodb.NewImage.clientid,
                    "s3path" : record.dynamodb.NewImage.s3path,
                    "language" : record.dynamodb.NewImage.language,
                    "filename" : record.dynamodb.NewImage.filename,
                    "timecreated" : record.dynamodb.NewImage.timecreated,
                    "appid" : record.dynamodb.NewImage.appid,
                    "subtitle" :  record.dynamodb.NewImage.subtitle,
                    "host" : record.dynamodb.NewImage.host,
                    "mediatype" :  record.dynamodb.NewImage.mediatype,
                    "sourcemimtype" : record.dynamodb.NewImage.sourcemimetype,
                  }
        };
        
           console.log("my UP HERE");
           ddb.putItem(params, function(err,data) {
               console.log("my HERE");
           if (err) {
              console.log("my  INSERTING Error", JSON.stringify(err, null, 2));
           } else {
              console.log("my  INSERTING Success",JSON.stringify(data, null, 2));
              console.log("my  COMPLETED INSERTION MODULE");
           }
           });
           
        
        }

        
        if (record.eventName == 'REMOVE') {
           console.log('my  DELETING RECORD');
           
                   var params = {
            TableName: 'myplugin_temp',
            Item: {
                    "client" : record.dynamodb.NewImage.client,
                    "expiration" : record.dynamodb.NewImage.expiration,
                    "notificationurl" : record.dynamodb.NewImage.notificationurl,
                    "clientid" : record.dynamodb.NewImage.clientid,
                    "s3path" : record.dynamodb.NewImage.s3path,
                    "language" : record.dynamodb.NewImage.language,
                    "filename" : record.dynamodb.NewImage.filename,
                    "timecreated" : record.dynamodb.NewImage.timecreated,
                    "appid" : record.dynamodb.NewImage.appid,
                    "subtitle" :  record.dynamodb.NewImage.subtitle,
                    "host" : record.dynamodb.NewImage.host,
                    "mediatype" :  record.dynamodb.NewImage.mediatype,
                    "sourcemimtype" : record.dynamodb.NewImage.sourcemimetype,
                  }
        };
           
           ddb.deleteItem(params, function(err, data) {
           if (err) {
              console.log("my  DELETING Error", JSON.stringify(err, null, 2));
           } else {
              console.log("my  DEL Success", JSON.stringify(data, null, 2));
           }
           });
           
        }
        
        if (record.eventName == 'MODIFY') {
           console.log('my  MODIFYING RECORD');
           
            var params = {
            TableName: 'myplugin_temp',
            Item: {
                    "client" : record.dynamodb.NewImage.client,
                    "expiration" : record.dynamodb.NewImage.expiration,
                    "notificationurl" : record.dynamodb.NewImage.notificationurl,
                    "clientid" : record.dynamodb.NewImage.clientid,
                    "s3path" : record.dynamodb.NewImage.s3path,
                    "language" : record.dynamodb.NewImage.language,
                    "filename" : record.dynamodb.NewImage.filename,
                    "timecreated" : record.dynamodb.NewImage.timecreated,
                    "appid" : record.dynamodb.NewImage.appid,
                    "subtitle" :  record.dynamodb.NewImage.subtitle,
                    "host" : record.dynamodb.NewImage.host,
                    "mediatype" :  record.dynamodb.NewImage.mediatype,
                    "sourcemimtype" : record.dynamodb.NewImage.sourcemimetype,
                  }
        };
        
           ddb.updateItem(params, function(err,data) {
           if (err) {
              console.log("my  UPDATING Error", JSON.stringify(err, null, 2));
           } else {
              console.log("my  UPDATING Success",JSON.stringify(data, null, 2));
           }
           });
        }
    });
    
    //callback(null, `my  Successfully processed  records.`);
    console.log(JSON.stringify(callback, null, 2));
};  
4

1 回答 1

0

好吧,需要强调一些注意事项:

  1. AWS.SharedIniFileCredentials 应加载用户主目录的特定路径。在 linux 上,它将位于/home/[user]/.aws/credentials上。而 lambda 函数无法访问该系统路径。换句话说,AWS.SharedIniFileCredentials 可以在您有权访问主目录的系统上实施。

    从共享凭证文件加载 Node.js 中的凭证

    有两种方法可以设置 lambda 访问 aws 服务的权限,即 dynamodb :

  2. 记住要了解 javascript 上的异步和同步过程。在您的 lambda 函数上,您会错过这部分,例如:

    // it is a promise function that running async process
    ddb.putItem(params, function(err,data) {
      ...
    })
    

    我更愿意建议使用最新的方法更改代码,并且 aws 承诺最佳实践,如下所示:

    exports.handler = async (event) => {
      try {
        let allTasks = [];
        event.Records.forEach((record) => {
          // set params here
          allTasks.push(ddb.putItem(params).promise());
    
          ...
        })
        if (allTasks.length > 0) {
          return Promise.all(allTasks).then(results => {
            console.log(results)
          })
        }
        return
      } catch(e) {
        console.log(e)
        throw e
      }
    }
    
于 2020-11-17T04:10:01.173 回答