Textract 在 Lambda 上运行时无法从 S3 读取对象

问题描述 投票:0回答:2

我有一个简单的 Lambda 函数,当文件上传到 S3 时,它应该调用 Textract。但是,当我从桌面运行 Lambda 函数时,对 Textract 的调用可以正常工作,而当我从 Lambda 环境运行完全相同的代码时,对 Textract 的调用就不起作用。

这是 Lambda 代码:

import os
import boto3

TEXTRACT_CLIENT = boto3.client('textract', region_name=os.environ['REGION'])


def lambda_handler(event, context):
    event_source = event['Records'][0]['s3']

    textract_ticket = TEXTRACT_CLIENT.start_document_analysis(
        DocumentLocation={
            'S3Object': {
                'Bucket': os.environ['REQUESTS_BUCKET'],
                'Name': event_source['object']['key']

            }
        },
        FeatureTypes=["TABLES", "FORMS"],
        NotificationChannel={
            'RoleArn': os.environ['TEXTRACT_ROLE_ARN'],
            'SNSTopicArn': os.environ['SNS_TOPIC_ARN']
        },
        OutputConfig={
            'S3Bucket': os.environ['RESULTS_BUCKET']
        }
    )

    return {
        'statusCode': 200,
        'JobId': textract_ticket['JobId']
    }

代码没有什么特别的。我在 Lambda 环境和本地计算机中对所有环境变量使用完全相同的值。在这两种情况下,我都使用相同的事件,指向相同的 S3 对象:

{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-1",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "my-bucket",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "35264254-7aa6-4f24-815a-f73e1671f151.pdf",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}

奇怪的是,当从我的桌面调用时,所有这些都会成功执行,但是当我从 Lambda 运行时,我得到:

{
  "errorMessage": "An error occurred (InvalidS3ObjectException) when calling the StartDocumentAnalysis operation: Unable to get object metadata from S3. Check object key, region and/or access permissions.",
  "errorType": "InvalidS3ObjectException",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 10, in lambda_handler\n    textract_ticket = TEXTRACT_CLIENT.start_document_analysis(\n",
    "  File \"/var/runtime/botocore/client.py\", line 386, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
    "  File \"/var/runtime/botocore/client.py\", line 705, in _make_api_call\n    raise error_class(parsed_response, operation_name)\n"
  ]
}

我在这里遗漏了什么吗?我不知道 Lambda 环境中可能出现什么问题。

amazon-web-services amazon-s3 aws-lambda amazon-textract
2个回答
2
投票

@Ronan Cunningham 和 @stijndepestel 的直觉都是正确的。

我对角色感到困惑。此示例涉及两个角色:Lambda 角色和 Textract 运行所在的角色。我错误地认为 Textract 角色用于其完整执行(Textract 角色具有完整的 S3 访问权限),但它仅用于发送 SNS 通知。但实际上 textract 在分配给 Lambda 的相同角色下运行,而 Lambda 没有 S3 访问权限。为 Lambda 角色添加 S3 访问权限后,一切按预期运行。

谢谢大家!


0
投票

提醒其他遇到此错误的人。 OP 是正确的,需要设置的是 Lambda 权限,而不是角色的权限,角色只需要 SNS 权限(不是其他 google 结果错误指出的 SQS)。如果您根本没有设置权限并且只有读取权限,AWS 会给出 2 个不同的错误。

如果 Lambda 缺乏读取权限,它将输出一个错误,提示“检查权限/对象”,如果它具有读取权限,它将输出 500 错误并显示不同的消息。

s3:GetObject
设置为
s3:PutObject
时,Lambda 需要
OutputConfig
StartDocumentTextDetectionCommand

            - Effect: Allow
              Action:
                  - s3:GetObject
                  - s3:PutObject
              Resource:
                  - arn:aws:s3:::<bucket_name>*

texttract 命令需要仅具有

sns:Publish
权限的角色:

                    - PolicyName: MyPolicyName
                      PolicyDocument:
                          Version: '2012-10-17'
                          Statement:
                              - Effect: Allow
                                Action: sns:Publish
                                Resource: !Ref <MySNSTopic>

只是为了通过稍微扩展答案来节省其他人的时间。

© www.soinside.com 2019 - 2024. All rights reserved.