amazon-web-services - 将 AWS S3 地形化为 Lambda 通知触发器

标签 amazon-web-services amazon-s3 aws-lambda terraform

我正在尝试编写要使用 S3 触发的 lambda 函数。 Lambda 函数创建成功,但“aws_s3_bucket_notification”资源在 terraform:apply 失败与 MethodNotAllowed错误 status code 405 :

Error: Error applying plan:
20-Sep-2018 15:23:53    1 error(s) occurred:
20-Sep-2018 15:23:53    * aws_s3_bucket_notification.my-trigger: 1 error(s) occurred:
20-Sep-2018 15:23:53    * aws_s3_bucket_notification.my-trigger: Error putting S3 notification configuration: MethodNotAllowed: The specified method is not allowed against this resource.
20-Sep-2018 15:23:53            status code: 405, request id:<hidden>, host id:<hidden>

这是我设置通知触发器的代码:
resource "aws_s3_bucket_notification" "my-trigger" {
  bucket = "my-bucket"

  lambda_function {
    lambda_function_arn = "${aws_lambda_function.my-function.arn}"
    events              = ["s3:ObjectCreated:*"]
    filter_prefix       = "file-prefix"
    filter_suffix       = "file-extension"
  }
}

这是从 S3 触发 Lambda 的权限:
resource "aws_lambda_permission" "s3-lambda-permission" {
  statement_id  = "AllowExecutionFromS3Bucket"
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.my-function.arn}"
  principal     = "s3.amazonaws.com"
  source_arn    = "arn:aws:s3:::my-bucket"
}

提前致谢!

最佳答案

所以我尝试了和你一样的设置,

...
// lambda resource

resource "aws_s3_bucket_notification" "my-trigger" {
    bucket = "my-bucket"

    lambda_function {
        lambda_function_arn = "${aws_lambda_function.my-function.arn}"
        events              = ["s3:ObjectCreated:*"]
        filter_prefix       = "AWSLogs/"
        filter_suffix       = ".txt"
    }
}

resource "aws_lambda_permission" "test" {
  statement_id  = "AllowS3Invoke"
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.my-function.arn}"
  principal = "s3.amazonaws.com"
  source_arn = "arn:aws:s3:::my-bucket"
}

...

我的 S3 存储桶策略是这样的:
{
    "Version": "2012-10-17",
    "Id": "AWSConsole-AccessLogs-Policy-1534800162725",
    "Statement": [
        {
            "Sid": "AWSConsoleStmt-1534800162725",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-bucket/AWSLogs/123456789012/*"
        }
    ]
}

并且成功创建了 s3 通知。

所以我认为现在你应该检查两件事:
  • 确保在 s3 通知之前实际创建了 aws_lambda_permission。我正在使用 terraform 0.10.2,但以前版本中可能存在错误,因此在 s3 通知之前不会创建此 lambda 权限。
  • 检查您的 s3 存储桶策略。它可能明确拒绝 lambda 访问。如果有的话,一定要摆脱那些。
  • 关于amazon-web-services - 将 AWS S3 地形化为 Lambda 通知触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52448714/

    相关文章:

    amazon-web-services - 如何修复 : "AccessDeniedException: You are in ap-southeast-1, but your directory region is us-east-1. Please use us-east-1 as region."

    android - 无法在 s3 中获取更新的对象?

    java - 如何对 aws lambda 调用进行单元测试?

    javascript - 通过iframe上传Amazon S3

    java - 有没有办法使用 Android AWS SDK 从 Amazon S3 存储桶读取文件上下文,而无需下载文件?

    amazon-web-services - 从 API 网关自定义授权方返回的 401 缺少 'Access-Control-Allow-Origin' header

    amazon-web-services - 使用 AWS Lambda 函数写入 Kinesis 流

    JavaScript:顺序迭代 Promise 函数

    amazon-s3 - S3 存储桶位于同一可用区

    amazon-s3 - Lambda 函数和触发的 S3 事件