对于来自 lambda 的 SQS 的跨账户访问,我是否需要允许附加到 lambda 的 IAM 角色拥有 SQS 权限,或者允许 IAM 角色在 SQS 的访问策略中拥有权限? (或者两者都做?)
更新:基本上我按照以下一些答案中的建议设置了 SQS 访问策略。
我得到一个
<块引用>AWS.SimpleQueueService.NonExistentQueue
当尝试从 lambda 向队列 (
boto3.resource('sqs').Queue(" some queue_url").send_message(**kwargs))` 发送内容时,我想知道是否有权限需要显式添加到 IAM 角色本身以允许发送到队列。
在 lambda(在 us-west-1 中)发送到 SQS 的代码如下:
import boto3
from botocore.config import Config
def lambda_handler(event, context):
boto3.resource('sqs').Queue('https://sqs.us-east-1.amazonaws.com/sqs_accnt_num/name_of_sqs').send_message(MessageBody="SomeMessageJSONDUMP")
SQS 访问策略如下:
{
"Version": "2012-10-17"
"Id": "SomeID",
"Statement" : [
{
"Sid": "somesid",
"Effect": "Allow",
"Principal": "*",
"Action": "SQS:SendMessage",
"Resource":"arn:aws:sqs:us-east-1:sqs_accnt_num:name_of_sqs",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:iam::lambda_accnt_num:role/name:"
}
}
},
{
"Sid": "somesid2",
"Effect": "Deny",
"Principal": "*",
"Action": "sqs:*",
"Resource": "*",
"Condition": {
"Bool": {
"aws:secureTransport": "false"
}
}
}
]}
更新:问题已解决:
所以看起来问题出在 SQS 访问策略中。出于某种原因,在我进行条件检查时的原始政策中,如:
"Sid": "somesid",
"Effect": "Allow",
"Principal": "*",
"Action": "SQS:SendMessage",
"Resource":"arn:aws:sqs:us-east-1:sqs_accnt_num:name_of_sqs",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:iam::lambda_accnt_num:role/name:"
}
}
然后,在尝试从 lambda 发送消息时,我仍然收到“拒绝访问”错误。但是正如 John Rotenstein 在他的回答中所建议的那样,我完全删除了 Condition
子句,并将 iam 角色 arn 直接放在 Principal 中,如下所示:
"Sid": "somesid2",
"Effect": "Allow",
"Principal": {
"AWS":"arn:aws:iam::lambda_accnt_num:role/name:"
},
"Action": "sqs:*",
"Resource": "arn:aws:sqs:us-east-1:sqs_accnt_num:name_of_sqs"
成功了! 虽然问题已解决,但有谁知道为什么我的原始政策(带有 Condition 条款)不起作用?我认为政策本身没有任何问题。
John Rotenstein 的回答中的一个小警告;对于来自 lambda 的跨区域 sqs 访问,您必须添加 region_name
字段来表示 sqs 所在的区域,同时创建 sqs_resource,如下所示:
boto3.resource('sqs', region_name='us-east-1')
此外,如果您在 SQS 中启用了加密,请确保您的 lambda 具有 KMS 权限,并且允许从 lambda 帐户访问 SQS 拥有的 KMS 密钥。
答案 0 :(得分:1)
这取决于你将如何做到这一点。一种方法是:
assume-role
权限,因此它可以承担来自 SQS 帐户的角色。assume-role
以获取临时凭据以在 SQS 帐户中执行操作。另一种方式是通过基于 SQS 资源的策略,这将允许 lambda 角色向其提交消息。
答案 1 :(得分:1)
Amazon SQS 队列可以获得访问策略。
此策略允许您授予实体访问队列的权限,包括来自其他 AWS 账户的实体。
因此,您可以简单地编辑 SQS 队列上的访问策略,以允许从 AWS Lambda 函数使用的 IAM 角色的 ARN 进行访问。
以下是来自 Identity and access management in Amazon SQS - Amazon Simple Queue Service 的示例:
<块引用>以下示例 Amazon SQS 策略授予 AWS 账户 111122223333 向 AWS 账户 444455556666 拥有的 queue2 发送和接收的权限。
{
"Version": "2012-10-17",
"Id": "UseCase1",
"Statement" : [{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": [
"111122223333"
]
},
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:us-east-2:444455556666:queue2"
}]
}
您应该能够更改 Principal
以引用正在使用的特定 IAM 角色。
更新:为了重现您的情况,我执行了以下操作:
Role-A
策略为账户 A(发送账户)中的 Lambda 创建 IAM 角色 AmazonSQSFullAccess
Queue-B
:{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-B:root"
},
"Action": "SQS:*",
"Resource": "arn:aws:sqs:ap-southeast-2:Account-B:queue-b"
},
{
"Sid": "__sender_statement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-A:role/role-a"
},
"Action": "SQS:SendMessage",
"Resource": "arn:aws:sqs:ap-southeast-2:Account-B:queue-b"
}
]
}
Lambda-A
以向 Queue-B
发送消息:import boto3
def lambda_handler(event, context):
sqs_resource = boto3.resource('sqs')
queue = sqs_resource.Queue('https://sqs.ap-southeast-2.amazonaws.com/Account-B/queue-b')
response = queue.send_message(MessageBody="SomeMessageJSONDUMP")
# Debug
print(response)
调试日志条目为:
<块引用>{'MD5OfMessageBody': '...', 'MessageId': '...', 'ResponseMetadata': {'RequestId': '...', 'HTTPStatusCode': 200, 'HTTPHeaders': { 'x-amzn-requestid': '...', 'date': 'Fri, 30 Jul 2021 23:25:40 GMT', 'content-type': 'text/xml', 'content-length': '378'}, 'RetryAttempts': 0}}
消息已成功接收: