使用Boto3向S3发送S3 Put Requests

时间:2018-04-22 00:45:31

标签: amazon-s3 boto3

我正在尝试将S3发送请求发送到SNS主题。我的代码如下所示:

s3.put_bucket_notification_configuration(
    Bucket=event_name,
    NotificationConfiguration={
        'TopicConfigurations': [
            {
                'TopicArn': sns_arn,
                'Events': [
                    's3:ObjectCreated:*',
                    ],
            },
        ]
    }
)

不幸的是,我得到了例外。

 File "./infra_setup.py", line 73, in setup_s3_event_listener
    's3:ObjectCreated:*',
  File "/home/ec2-user/.local/lib/python2.7/site-packages/botocore/client.py", line 314, in _api_call
return self._make_api_call(operation_name, kwargs)
  File "/home/ec2-user/.local/lib/python2.7/site-packages/botocore/client.py", line 612, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when 
calling the PutBucketNotificationConfiguration operation: Access Denied

我无法使用Boto3找到这个在线示例 - 我正在避开控制台,因为我需要使其可重现。

如何为bucket / sns主题提供必要的权限?

执行此脚本的EC2具有完整的SNS和S3访问权限,这是值得的。

更新:

是的,非常愚蠢。我之前使用BucketAlreadyExists创建了我的存储桶失败 - 我以为它存在于我的帐户中,但事实并非如此。将名称更改为唯一的名称可以解决该错误,而不是产生此错误:

botocore.exceptions.ClientError: An error occurred (InvalidArgument) when calling the PutBucketNotificationConfiguration operation: Unable to validate the following destination configurations

再一次,我找不到关于在boto3 中解决这个的好信息。

1 个答案:

答案 0 :(得分:0)

这里是如何配置S3以使用boto3将推入事件推送到SNS的示例。请注意,它会完全覆盖SNS主题策略。

import json
import boto3

# assumes an sns topic, bucket, and queue are all created

session = boto3.session.Session(
    aws_access_key_id=<ACCESS_ID>,
    aws_secret_access_key=<SECRET_KEY>,
)
bucket_name = <BUCKET_NAME>
topic_name = <TOPIC_NAME>

sns_resource = self.session.resource('sns')
sns_topic = sns_resource.create_topic(Name=topic_name)  # get or create

# set up SNS policy
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/
sns.html#SNS.Client.set_topic_attributes

sns_topic_policy = {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "sns:Publish",
            "Resource": sns_topic.arn,
            "Condition": {
                "ArnLike": {"AWS:SourceArn": f"arn:aws:s3:*:*:{bucket_name}"},
            },
        },
    ],
}
sns_client = session.client('sns')
sns_client.set_topic_attributes(
    TopicArn=sns_topic.arn,
    AttributeName='Policy',
    AttributeValue=json.dumps(sns_topic_policy),
)

# set up notification config
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.BucketNotification.put

s3_resource = session.resource('s3')
bucket_notification = s3_resource.BucketNotification(bucket_name)
s3_notification_config = {
    'TopicConfigurations': [
        {
            'TopicArn': sns_topic.arn,
            'Events': [
                's3:ObjectCreated:*',
            ],
        },
    ],
}
response = bucket_notification.put(NotificationConfiguration=s3_notification_config)