S3 Bucket Lambda事件:无法验证以下目标配置

Sco*_*ner 15 lambda amazon-s3 amazon-web-services node.js aws-sdk

我正在尝试创建一个S3存储桶并立即为其分配一个lambda通知事件.

这是我写的节点测试脚本:

const aws = require('aws-sdk');
const uuidv4 = require('uuid/v4');

aws.config.update({
  accessKeyId: 'key',
  secretAccessKey:'secret',
  region: 'us-west-1'
});

const s3 = new aws.S3();

const params = {
  Bucket: `bucket-${uuidv4()}`,
  ACL: "private",
  CreateBucketConfiguration: {
    LocationConstraint: 'us-west-1'
  }
};

s3.createBucket(params, function (err, data) {
  if (err) {
    throw err;
  } else {
    const bucketUrl = data.Location;

    const bucketNameRegex = /bucket-[a-z0-9\-]+/;
    const bucketName = bucketNameRegex.exec(bucketUrl)[0];

    const params = {
      Bucket: bucketName,
      NotificationConfiguration: {
        LambdaFunctionConfigurations: [
          {
            Id: `lambda-upload-notification-${bucketName}`,
            LambdaFunctionArn: 'arn:aws:lambda:us-west-1:xxxxxxxxxx:function:respondS3Upload',
            Events: ['s3:ObjectCreated:CompleteMultipartUpload']
          },
        ]
      }
    };

    // Throws "Unable to validate the following destination configurations" until an event is manually added and deleted from the bucket in the AWS UI Console
    s3.putBucketNotificationConfiguration(params, function(err, data) {
      if (err) {
        console.error(err);
        console.error(this.httpResponse.body.toString());
      } else {
        console.log(data);
      }
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

创建工作正常,但呼吁s3.putBucketNotificationConfigurationaws-sdk抛出:

{ InvalidArgument: Unable to validate the following destination configurations
    at Request.extractError ([...]/node_modules/aws-sdk/lib/services/s3.js:577:35)
    at Request.callListeners ([...]/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit ([...]/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit ([...]/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition ([...]/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo ([...]/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at [...]/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> ([...]/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> ([...]/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners ([...]/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
  message: 'Unable to validate the following destination configurations',
  code: 'InvalidArgument',
  region: null,
  time: 2017-11-10T02:55:43.004Z,
  requestId: '9E1CB35811ED5828',
  extendedRequestId: 'tWcmPfrAu3As74M/0sJL5uv+pLmaD4oBJXwjzlcoOBsTBh99iRAtzAloSY/LzinSQYmj46cwyfQ=',
  cfId: undefined,
  statusCode: 400,
  retryable: false,
  retryDelay: 4.3270874729153475 }

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>InvalidArgument</Code>
    <Message>Unable to validate the following destination configurations</Message>
    <ArgumentName1>arn:aws:lambda:us-west-1:xxxxxxxxxx:function:respondS3Upload, null</ArgumentName1>
    <ArgumentValue1>Not authorized to invoke function [arn:aws:lambda:us-west-1:xxxxxxxxxx:function:respondS3Upload]</ArgumentValue1>
    <RequestId>9E1CB35811ED5828</RequestId>
    <HostId>tWcmPfrAu3As74M/0sJL5uv+pLmaD4oBJXwjzlcoOBsTBh99iRAtzAloSY/LzinSQYmj46cwyfQ=</HostId>
</Error>
Run Code Online (Sandbox Code Playgroud)

我使用分配给lambda的角色运行它,我认为它是所需的所有策略.我可能会遗漏一些东西.我正在使用我的root访问键来运行此脚本.

角色

我想这可能是其中S3需要时间添加事件之前创造的水桶一个计时错误,但我等了一会儿,硬编码区名称,并重新运行我的脚本会抛出同样的错误.

奇怪的是,如果我在S3 UI中创建事件挂钩并立即将其删除,那么如果我将该桶名称硬编码到其中,我的脚本就会起作用.似乎在UI中创建事件会添加一些所需的权限,但我不确定在SDK或控制台UI中会出现什么.

S3事件配置

有什么想法或事情要尝试吗?谢谢你的帮助

小智 24

您收到此消息是因为您的s3存储桶缺少调用lambda函数的权限.

根据AWS文档!需要两种类型的权限:

  1. Lambda函数调用服务的权限
  2. Amazon S3调用Lambda函数的权限

您应该创建一个'AWS :: Lambda :: Permission'类型的对象,它应该类似于:

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "<optional>",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "<ArnToYourFunction>",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "<YourAccountId>"
        },
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:s3:::<YourBucketName>"
        }
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

  • 我应该在哪里添加上述政策文件? (7认同)
  • 添加位置:转到 Lambda &gt; 选择您的函数 -&gt; 配置 -&gt; 权限 -&gt; 基于资源的策略 -&gt; 添加权限 -&gt; AWS 服务 -&gt; S3 -&gt; 填充向导,使用 `lambda:InvokeFunction` (4认同)
  • 我们也面临着同样的问题。我们需要在哪里添加此政策? (2认同)
  • 如何在 `terraform` 中创建:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission (2认同)

Sco*_*ner 5

一年后终于再次看着这个。这是我们去年取消的黑客马拉松项目。@ davor.obilinovic的回答非常有帮助,使我指向需要添加的Lambda权限。还是花了我一点时间才弄清楚我需要它看起来像什么。

这是AWS JavaScript SDK和Lambda API文档 https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#addPermission-property https://docs.aws.amazon.com/lambda/latest /dg/API_AddPermission.html

JS SDK文档包含以下内容:

SourceArn: "arn:aws:s3:::examplebucket/*",
Run Code Online (Sandbox Code Playgroud)

我无法使它工作最长时间,但仍然Unable to validate the following destination configurations出现错误。

更改为

SourceArn: "arn:aws:s3:::examplebucket",
Run Code Online (Sandbox Code Playgroud)

解决了该问题。这/*显然是错误的,我应该仔细看一下我在这里得到的答案,但是正在尝试关注AWS文档。

经过一段时间的开发并创建了很多存储桶,Lambda权限和S3 Lambda通知后,调用addPermission开始引发The final policy size (...) is bigger than the limit (20480).对每个存储桶添加新的,单独的权限,将它们添加到Lambda函数策略的底部,并且显然该策略具有最大大小。

该策略在AWS管理控制台中似乎不可编辑,因此我很高兴用SDK删除了每个条目。我复制了策略JSON,将Sids拉出并removePermission循环调用(这引发了速率限制错误,我不得不运行多次)。

最终,我发现省略SourceArn密钥将使Lambda拥有所有S3存储桶的权限。

这是我使用SDK添加所需权限的最终代码。我只为功能运行一次。

SourceArn: "arn:aws:s3:::examplebucket/*",
Run Code Online (Sandbox Code Playgroud)