使用来自另一个帐户(us-east-1)的密钥加密 sqs 队列(us-east-2)并使用 lambda 访问它 - 面临错误

Encrypting an sqs queue(us-east-2) using a key from another account(us-east-1) and access it using lambda - facing error

考虑两个帐户帐户 A 和帐户 B。我们必须使用帐户 A 中的 KMS 密钥加密帐户 B 中的 SQS 队列,然后使用 lambda(在帐户 A 中)向队列发送和接收消息). SQS CFN 模板:

MyQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Ref QueueName
      DelaySeconds: '0'
      MaximumMessageSize: '262144'
      MessageRetentionPeriod: '345600'
      ReceiveMessageWaitTimeSeconds: '0'
      VisibilityTimeout: '30'
      KmsMasterKeyId: <Key_id of the custom CMK> (I have a doubt here also, should i input the key id or the alias of my key?)

主要政策:

{
    "Version": "2012-10-17",
    "Id": "key-consolepolicy-3",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::<Account_B_id>:root",
                    "arn:aws:iam::<Account_A_id>:root",
                    "arn:aws:iam::<Account_A_id>:role/lambda-execution-role"
                ]
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<Account_A_id>:role/lambda-execution-role"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion",
                "kms:ReplicateKey",
                "kms:UpdatePrimaryRegion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::<Account_B_id>:root",
                    "arn:aws:iam::<Account_A_id>:role/lambda-execution-role"
                ]
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::<Account_B_id>:root",
                    "arn:aws:iam::<Account_A_id>:role/lambda-execution-role"
                ]
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

SQS 队列策略:


{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<Account_A_id>:role/lambda-execution-role"
      },
      "Action": "sqs:*",
      "Resource": "arn:aws:sqs:us-east-2:<Account_B_id>:queue"
    }
  ]
}

Lambda 函数 - Python 向队列发送和接收消息的代码:

import json
import boto3
def lambda_handler(event, context):
    sqs = boto3.client('sqs', region_name='us-east-2')
    queue_url = 'https://sqs.us-east-2.amazonaws.com/<Account_B_id>/queue'
    response = sqs.send_message(QueueUrl=queue_url,DelaySeconds=0,MessageBody=('hey there 123 !'))
    response1 = sqs.send_message(QueueUrl=queue_url,DelaySeconds=0,MessageBody=('hey there 1234 !'))
    response2 = sqs.send_message(QueueUrl=queue_url,DelaySeconds=0,MessageBody=('hey there 123345 !'))
    print('message sent')
    response5 = sqs.receive_message(
    QueueUrl=queue_url,
    AttributeNames=['All'],
    MaxNumberOfMessages=10,
    WaitTimeSeconds=7)
    message = response5['Messages'][0]['Body']
    print(message) 

完成所有这些事情后,我在 lambda 中创建了一个测试事件并对其进行了测试。出现以下错误:

[ERROR] ClientError: An error occurred (KMS.AccessDeniedException) when calling the SendMessage operation: null (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: d6913dbc-e22f-4ccf-ba5a-9844ab1156e0; Proxy: null)
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 6, in lambda_handler
    response = sqs.send_message(QueueUrl=queue_url,DelaySeconds=0,MessageBody=('hey there 123 !'))
  File "/var/runtime/botocore/client.py", line 386, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 705, in _make_api_call
    raise error_class(parsed_response, operation_name)

在没有 KMS 的情况下,此设置有效。有人可以帮助我将 KMS 集成到其中吗?

为了解决这个问题,我联系了 AWS Support 并获得了解决方案。最初我将我的密钥输入 us-east-1 并尝试使用它。为了访问 us-east-2 中的 SQS,密钥也必须在 us-east-2 中。所以向我建议的解决方案是,在 us-east-2 中创建密钥的副本并输入副本密钥的 arn (我在这里也犯了一个错误,我在cfn 模板) 在 cloudformation 模板中 (因为我使用的是 multi-region 密钥)。如果它不是 multi-region 密钥,我们必须在 SQS 队列的同一区域中创建一个新密钥。