boto3:使用 IAM 角色的 S3 存储桶放置事件通知失败

boto3: S3 bucket put event notification failing using IAM Role

我遇到了一种情况,我正在尝试使用 IAM 角色为 SQS 配置 S3 存储桶上的事件通知。

它适用于 aws_access_key_id 和 aws_secret_key_id,但不适用于角色 ARN。

作品:

client = boto3.client(
    's3',
    aws_access_key_id='XXXXXXXXXXXX',
    aws_secret_access_key='XXXXXXXXXXXXXXX'
)

bucket_notifications_configuration = {
    'QueueConfigurations': [{
        'Events': ['s3:ObjectCreated:*'],
        'Id': 'Test',
        'QueueArn':'<SQS ARN>'
    }]
}

client.put_bucket_notification_configuration(
    Bucket=bucket_name,
    NotificationConfiguration=bucket_notifications_configuration)

但出于安全原因,我们试图使用 IAM 角色而不是 ID 来获得相同的结果,但我找不到任何有效的东西。尝试使用 'sts',仍然没有成功。获取错误 - "not authorized to perform: sts:AssumeRole on resource:"

无效:

client = boto3.client(
    's3',
    role_arn = <IAM Role ARN>
)

bucket_notifications_configuration = {
    'QueueConfigurations': [{
        'Events': ['s3:ObjectCreated:*'],
        'Id': 'Test',
        'QueueArn':<SQS ARN>
    }]
}

client.put_bucket_notification_configuration(
    Bucket=bucket_name,
    NotificationConfiguration=bucket_notifications_configuration)

还尝试在初始化客户端时不提供 Access/Secret 密钥或角色的情况下授予此 lambda 角色 运行 的完全 s3 访问权限。但它抱怨访问被拒绝。

有人可以帮忙吗?

如果您提供 IAM 角色 ARN,那么您用于代入该角色的凭证需要具有代入该角色的权限。是吗?

除此之外,听起来您是 运行 Lambda 中的这段代码。如果那是真的,那么您为什么要明确承担您的 Lambda 代码中的角色?您通常会为 Lambda 分配一个 IAM 角色,该角色已经包含放置存储桶通知配置的权限,然后您不需要承担任何事情。

最后,在 Lambda 函数(通常是经常调用的函数)中配置事件通知似乎很奇怪。你确定这是正确的吗?

要使用角色获取临时凭证,您需要调用assume_role。这意味着您还需要进行身份验证和授权。

您不能使用 root 凭据调用代入角色。您必须使用 IAM 凭证或临时凭证。您使用的凭据必须具有 "Trust Relationship" 才能承担角色。

注意:由于您使用的是 Lambda,因此您实施此错误。您需要为您的 Lambda 函数分配一个 IAM 角色,然后系统会在您的 boto3.client('s3') 函数调用中自动检测您的凭据。

AWS Lambda Permissions Model

以下代码将展示如何在您的示例中使用 assume_role,忽略我刚才提到的关于 Lambda IAM 角色的细节。

client = boto3.client(
    'sts',
    aws_access_key_id='XXXXXXXXXXXX',
    aws_secret_access_key='XXXXXXXXXXXXXXX')

response = client.assume_role(
        RoleArn='arn:aws:iam::012345678901:role/example-role',
        RoleSessionName='ExampleSessionName')

session = boto3.Session(
    aws_access_key_id=response['Credentials']['AccessKeyId'],
    aws_secret_access_key=response['Credentials']['SecretAccessKey'],
    aws_session_token=response['Credentials']['SessionToken'])

s3 = session.client('s3')

bucket_notifications_configuration = {
    'QueueConfigurations': [{
        'Events': ['s3:ObjectCreated:*'],
        'Id': 'Test',
        'QueueArn':<SQS ARN>
    }]
}

s3.put_bucket_notification_configuration(
    Bucket=bucket_name,
    NotificationConfiguration=bucket_notifications_configuration)

终于成功了!!似乎您只需要为 Lambda 执行时分配的角色提供足够的权限(感谢@Michael-sqlbot)。如果你从本地机器 运行 它可能不起作用,因为你不能那样分配角色。

此外,请确保 S3 存储桶存在于您的 lambda 尝试修改的同一 AWS 环境中。否则您将收到拒绝访问错误。如果您的 S3 没有权限将消息发送到您尝试为通知添加的 SQS 队列,它会抛出错误消息 - 无法验证目标配置。