简体   繁体   English

无法在 AWS 中为 Lambda function 设置 S3 触发器

[英]Cannot set S3 trigger for Lambda function in AWS

I've been all over the internet looking for a solution to this.我一直在互联网上寻找解决方案。 I have been trying to setup an AWS Lambda function to send a message to SNS every time a file is uploaded to a particular S3 bucket, according to this tutorial .根据本教程,我一直在尝试设置 AWS Lambda function 以在每次将文件上传到特定 S3 存储桶时向 SNS 发送消息。 At this point, I have the function setup and I can invoke it successfully.至此,我已经设置了 function 并且可以成功调用它。 However, when I attempt to connect the function to S3, I get an error stating An error occurred (InvalidArgument) when calling the PutBucketNotification operation: Unable to validate the following destination configurations .但是,当我尝试将 function 连接到 S3 时,我收到一条错误消息,指出An error occurred (InvalidArgument) when calling the PutBucketNotification operation: Unable to validate the following destination configurations According to this article , I should be able to add a permission that will let S3 invoke the Lambda function, like this:根据这篇文章,我应该能够添加一个权限,让 S3 调用 Lambda function,如下所示:

aws lambda add-permission \
    --function-name my-file-upload \
    --principal s3.amazonaws.com \
    --statement-id AcceptFromImport \
    --action "lambda:InvokeFunction" \
    --source-arn arn:aws:s3:::file-import \
    --source-account my_account_id

I did this, and noticed that the policy associated with the Lambda function updated and appeared to be correct.我这样做了,并注意到与 Lambda function 相关的策略已更新并且似乎是正确的。 However, the error persists.但是,错误仍然存在。 I've looked at a similar question, here , but none of the solutions here worked.我在这里看过一个类似的问题,但这里的解决方案都没有奏效。

Execution Role ARN: arn:aws:iam::my_account_id:role/lambda-upload-stream执行角色 ARN: arn:aws:iam::my_account_id:role/lambda-upload-stream

Execution Role (lambda-upload-stream) trust relationship:执行角色(lambda-upload-stream)信任关系:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Execution Role policy (my-file-upload):执行角色策略(my-file-upload):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AccessObject",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::file-import/*"
        },
        {
            "Sid": "SendUpdate",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "arn:aws:sns:ap-northeast-1:my_account_id:comm-in"
        }
    ]
}

Lambda function ARN: arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload Lambda function ARN: arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload

Lambda function role document Lambda function 角色文档

{
  "roleName": "lambda-upload-stream",
  "policies": [
    {
      "name": "my-file-upload",
      "id": "AWS_ACCESS_KEY_ID",
      "type": "managed",
      "arn": "arn:aws:iam::my_account_id:policy/my-file-upload",
      "document": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Sid": "AccessObject",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::file-import/*"
          },
          {
            "Sid": "SendUpdate",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "arn:aws:sns:ap-northeast-1:my_account_id:comm-in"
          }
        ]
      }
    }
  ],
  "resources": {
    "s3": {
      "service": {
        "name": "Amazon S3",
        "icon": "data:image/svg+xml;base64,very_long_base64_string1"
      },
      "statements": [
        {
          "resource": "arn:aws:s3:::file-import/*",
          "service": "s3",
          "effect": "Allow",
          "action": "s3:GetObject",
          "source": {
            "index": "AccessObject",
            "policyName": "my-file-upload",
            "policyType": "managed"
          }
        }
      ]
    },
    "sns": {
      "service": {
        "name": "Amazon SNS",
        "icon": "data:image/svg+xml;base64,very_long_base64_string2"
      },
      "statements": [
        {
          "resource": "arn:aws:sns:ap-northeast-1:my_account_id:comm-in",
          "service": "sns",
          "effect": "Allow",
          "action": "sns:Publish",
          "source": {
            "index": "SendUpdate",
            "policyName": "my-file-upload",
            "policyType": "managed"
          }
        }
      ]
    }
  },
  "trustedEntities": [
    "lambda.amazonaws.com"
  ]
}

Lambda function resource policy: Lambda function 资源策略:

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "my_account_id"
        },
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:s3:::file-import"
        }
      }
    }
  ]
}

My question is: what am I doing wrong here and how do I fix it?我的问题是:我在这里做错了什么,我该如何解决?

The thing you need to create is called a "Resource-based policy", and is what should be created by aws lambda add-permission .您需要创建的东西称为“基于资源的策略”,应该由aws lambda add-permission创建。

A Resource-based policy gives S3 permission to invoke your lambda.基于资源的策略允许 S3 调用您的 lambda。 This is a property on your lambda itself, and is not part of your lambda's IAM role (Your lambda's IAM role controls what your lambda can do , a Resource-based policy controls who can do what to your lambda . You can view this resource in the UI on the aws console by going to your lambda, clicking "Permissions" and scrolling down to "Resource-based policy". The keyword you want to look out for is lambda:InvokeFunction , which is what gives other things permission to call your lambda, including other AWS accounts, and other AWS services on your account (like s3). This is a property on your lambda itself, and is not part of your lambda's IAM role (Your lambda's IAM role controls what your lambda can do , a Resource-based policy controls who can do what to your lambda . You can view this resource in通过转到您的 lambda,单击“权限”并向下滚动到“基于资源的策略”,在 aws 控制台上的 UI。您要注意的关键字是lambda:InvokeFunction ,这就是赋予其他事物调用您的权限的原因lambda,包括其他 AWS 账户,以及您账户上的其他 AWS 服务(如 s3)。

That being said, the command you ran should have created this policy.话虽如此,您运行的命令应该已创建此策略。 Did you make sure to replace my_account_id with your actual account id when you ran the command?您是否确保在运行命令时将my_account_id替换为您的实际帐户 ID?

In addition, make sure you replace --source-arn arn:aws:s3:::file-import with the actual ARN of your bucket (I assume you had to create a bucket with a different name because s3 buckets must have globally unique names, and file-import is almost surely already taken)此外,确保将--source-arn arn:aws:s3:::file-import替换为存储桶的实际 ARN(我假设您必须创建一个具有不同名称的存储桶,因为 s3 存储桶必须具有全局唯一性名称,并且几乎可以肯定已经使用了file-import

I figured out what the problem was.我弄清楚了问题所在。 My initial command was:我最初的命令是:

aws s3api put-bucket-notification --bucket azure-erp-import \
    --notification-configuration "CloudFunctionConfiguration={Id=file-uploaded,Events=[],Event=s3:ObjectCreated:*,CloudFunction=arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload,InvocationRole=arn:aws:iam::my_account_id:role/lambda-upload-stream}"

This failed because the arn:aws:iam::my_account_id:role/lambda-upload-stream role doesn't have permissions to call lambda:InvokeFunction on the lambda function.这失败了,因为arn:aws:iam::my_account_id:role/lambda-upload-stream角色无权调用lambda:InvokeFunction上 lambda ZC1C42145268E683985D Removing this value fixed the error.删除此值可修复错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM