amazon-web-services - 在 Lambda 上运行时,Textract 无法从 S3 读取对象
问题描述
我有一个简单的 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 环境中可能出现的问题。
解决方案
@Ronan Cunningham 和 @stijndepestel 的直觉都是正确的。
我对角色感到困惑。此示例涉及两个角色:Lambda 角色和运行 Textract 的角色。我错误地认为 Textract 角色用于其完整执行(Textract 角色具有完整的 S3 访问权限),但它仅用于发送 SNS 通知。但实际上 textract 在分配给 Lambda 的同一角色下运行,后者没有 S3 访问权限。将 S3 访问权限添加到 Lambda 角色后,一切都按预期工作。
感谢你们!
推荐阅读
- python - Pandas 使用多个条件在列中分配值:
- java - 使用 java nullpointerexception 显示背景图像
- mysql - 在 bash 中获取 MySQL 输出
- django-rest-framework - 脚本的哪一部分使 JSON API 作为 Django Rest Framework 中的对象数组返回?
- c# - 在 ControlTemplate 触发器中获取 WPF ContextMenu 打开方向
- gitlab - Gitlab-CI 非零退出成功
- css - Angular 的父组件应该如何设计子组件?我想要一个不会被弃用的好解决方案
- apache-flink - Flink-Dataset-Flink 可以尊重多个流/输入的处理顺序吗?
- c# - ASP .Net Core 2 自包含部署在不同应用程序池标识帐户下的 IIS 中出现 502.5 错误
- oracle - 具有多个条件和最大值的左连接