我使用构建的数据处理管道
S3+SNS+Lambda
因为S3无法在其存储区域外发送通知,所以我使用SNS向其他区域的Lambda发送S3通知。
用编码的lambda函数
from __future__ import print_function
import boto3
def lambda_handler (event, context):
input_file_bucket = event["Records"][0]["s3"]["bucket"]["name"]
input_file_key = event["Records"][0]["s3"]["object"]["key"]
input_file_name = input_file_bucket+"/"+input_file_key
s3=boto3.resource("s3")
obj = s3.Object(bucket_name=input_file_bucket, key=input_file_key)
response = obj.get()
return event #echo first key valuesdf
当我运行保存和测试时,我得到了以下错误
{
"stackTrace": [
[
"/var/task/lambda_function.py",
20,
"lambda_handler",
"response = obj.get()"
],
[
"/var/runtime/boto3/resources/factory.py",
394,
"do_action",
"response = action(self, *args, **kwargs)"
],
[
"/var/runtime/boto3/resources/action.py",
77,
"__call__",
"response = getattr(parent.meta.client, operation_name)(**params)"
],
[
"/var/runtime/botocore/client.py",
310,
"_api_call",
"return self._make_api_call(operation_name, kwargs)"
],
[
"/var/runtime/botocore/client.py",
395,
"_make_api_call",
"raise ClientError(parsed_response, operation_name)"
]
],
"errorType": "ClientError",
"errorMessage": "An error occurred (AccessDenied) when calling the GetObject operation: Access Denied"
}
我用配置了lambda角色
full S3 access
并在我的目标bucket 上设置bucket策略
everyone can do anything(list, delete, etc.)
我似乎没有制定好政策。
Omuthu的回答实际上正确地确定了我的问题,但它没有提供解决方案,所以我想我应该这样做。
当你在IAM中设置权限时,你可能会做出这样的事情:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::test"
]
}
]
}
不幸的是,这是不对的。您需要将Object权限应用于bucket中的对象。所以它看起来是这样的:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::test"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::test/*"
]
}
]
}
注意第二个ARN,其末尾没有/*
。
我遇到了一个类似的问题,我通过向用户附加适当的策略来解决它。
IAM->用户->用户名->权限->附加策略。
此外,请确保添加了正确的访问密钥和机密访问密钥,您可以使用AmazonCLI进行添加。
您正在查找的特定S3对象具有有限权限的可能性
- S3对象级读取权限被拒绝
- 附加到lambda的角色没有获取/读取S3对象的权限
- 如果使用S3存储桶策略授予访问权限,请验证是否提供了读取权限
添加到Amri的答案中,如果您的bucket是私有的,并且您有访问它的凭据,则可以使用boto3.client:
import boto3
s3 = boto3.client('s3',aws_access_key_id='ACCESS_KEY',aws_secret_access_key='SECRET_KEY')
response = s3.get_object(Bucket='BUCKET', Key='KEY')
*对于这个文件:s3://bucket/a/b/c/some.text,bucket是"bucket",Key是"a/b/c/some.text"
---编辑---
例如,您可以很容易地更改脚本以接受键作为环境变量,这样它们就不会被硬编码。为了简单起见,我留下了这样的
我也遇到过类似的问题,不同的是bucket是用KMS密钥加密的。
固定为:IAM->加密密钥->YOUR_AWS_KMS_KEY->到您的策略或帐户
在我的案例中,我运行的Lambda有一个角色blahblahRole
,而这个blahblahRole
没有S3 bucket的权限。
下面是一个可以添加到IAM Role
中的简单JSON IAM片段。尽管这为铲斗提供了FullAccess
,但通常不会成为问题,因为生产中的Lambda操作使用了专用铲斗。
但是,如果不需要FullAccess
,则需要单独添加那些抛出AccessDenied
错误的操作。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAllOnThisBucket",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "arn:aws:s3:::bucket_name/*"
}
]
}