【问题标题】:Cannot set S3 trigger for Lambda function in AWS无法在 AWS 中为 Lambda 函数设置 S3 触发器
【发布时间】:2021-05-01 00:26:47
【问题描述】:

我一直在互联网上寻找解决方案。根据this tutorial,我一直在尝试设置一个 AWS Lambda 函数,以便在每次将文件上传到特定的 S3 存储桶时向 SNS 发送一条消息。至此,我已经完成了函数设置,并且可以成功调用它。但是,当我尝试将该函数连接到 S3 时,我收到一条错误消息,指出 An error occurred (InvalidArgument) when calling the PutBucketNotification operation: Unable to validate the following destination configurations。根据this article,我应该能够添加一个允许 S3 调用 Lambda 函数的权限,如下所示:

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

我这样做了,并注意到与 Lambda 函数关联的策略已更新并且似乎是正确的。但是,错误仍然存​​在。我看过一个类似的问题,here,但这里的解决方案都不起作用。

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

执行角色(lambda-upload-stream)信任关系:

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

执行角色策略(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 函数 ARN:arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload

Lambda 函数角色文档

{
  "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 函数资源策略:

{
  "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"
        }
      }
    }
  ]
}

我的问题是:我在这里做错了什么以及如何解决?

【问题讨论】:

  • 为什么会有三个角色?这些用于3种不同的功能?什么是“角色文件”?它来自哪里?其 IAM 角色或策略无效。
  • @Marcin 角色文档是我在 AWS 控制台上查找 Lambda 函数时得到的,转到权限并单击 Role Document

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


【解决方案1】:

您需要创建的东西称为“基于资源的策略”,应该由aws lambda add-permission 创建。

基于资源的策略允许 S3 调用您的 lambda。这是您的 lambda 本身的属性,而不是您的 lambda IAM 角色的一部分(您的 lambda 的 IAM 角色控制 您的 lambda 可以做什么,基于资源的策略控制 谁可以做什么到您的 lambda。您可以在 aws 控制台的 UI 中查看此资源,方法是转到您的 lambda,单击“权限”并向下滚动到“基于资源的策略”。您要注意的关键字是lambda:InvokeFunction,它允许其他事物调用您的 lambda,包括其他 AWS 账户和您账户上的其他 AWS 服务(如 s3)。

话虽如此,您运行的命令应该已创建此策略。运行命令时,您是否确保将 my_account_id 替换为您的实际帐户 ID?

此外,请确保将 --source-arn arn:aws:s3:::file-import 替换为存储桶的实际 ARN(我假设您必须创建一个具有不同名称的存储桶,因为 s3 存储桶必须具有全局唯一名称,而 file-import 几乎肯定已经采取)

【讨论】:

  • 对不起,我忘了把它包括在问题中。它确实存在。
  • 至于您的其他部分,是的,我使用我的帐户 ID 和 S3 存储桶的实际 ARN 运行了添加权限。
  • 嗯,这很奇怪,文档对我来说看起来不错。我认为当您使用自己帐户中的 s3 存储桶时,可能不需要“帐户等于”条件。我想下一步将仔细检查您是否不小心在您运行的命令中的某处为您的存储桶/函数/帐户 ID 留下了占位符字符串
  • 可能是因为我在资源策略中从 lambda ARN 中省略了可能的版本或别名?
【解决方案2】:

我发现了问题所在。我最初的命令是:

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}"

这失败了,因为 arn:aws:iam::my_account_id:role/lambda-upload-stream 角色没有权限在 lambda 函数上调用 lambda:InvokeFunction。删除此值可修复错误。

【讨论】:

    猜你喜欢
    • 2018-07-16
    • 1970-01-01
    • 2018-01-15
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多