如何授予向不同 AWS 账户中的 SQS 队列发送消息的权限?

Fab*_*oni 2 python amazon-sqs amazon-iam serverless-framework

我正在编写一个 Python 应用程序,该应用程序从帐户 A 中提取数据并将其发送到帐户 B 中的 SQS 队列。执行 lambda 函数时,它返回以下错误:

"errorMessage": "调用 SendMessage 操作时发生错误 (AccessDenied):访问资源https://eu-central-1.queue.amazonaws.com/被拒绝。",

如果我在同一帐户中使用 SQS 队列,它就可以工作。

我正在使用无服务器框架,我需要在跨账户角色中使用ExternalId 。

我做了什么:

在账户 A(执行 Lambda 函数的地方)

以下功能是使用Serverless框架部署的:

  TotalCollectorWeekToDate:
    handler: environment.total_wtd_summary_handler
    module: collectors
    memorySize: 128
    role: arn:aws:iam::<ACCOUNT_A>:role/FunctionsLambdaRole
    timeout: 30
    events:
      - schedule:
          rate: cron(0 7 * * ? *)
          enabled: true
    environment:
      COST_DATA_SQS_QUEUE_URL: https://sqs.eu-central-1.amazonaws.com/<ACCOUNT_B>/prod-analyser-queue
Run Code Online (Sandbox Code Playgroud)

角色

Resources:
  FunctionsLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: FunctionsLambdaRole
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: "sts:AssumeRole"
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
      Policies:
        - PolicyName: logs
          PolicyDocument:
            Statement:
              Effect: Allow
              Action:
                - "logs:CreateLogGroup"
                - "logs:CreateLogStream"
                - "logs:PutLogEvents"
              Resource: "arn:aws:logs:*:*:*"
        - PolicyName: lambda
          PolicyDocument:
            Statement:
              Effect: Allow
              Action:
                - "lambda:InvokeFunction"
              Resource: "*"
        - PolicyName: VPCAccess
          PolicyDocument:
            Statement:
              Effect: Allow
              Action:
                - "ec2:CreateNetworkInterface"
                - "ec2:DescribeNetworkInterfaces"
                - "ec2:DeleteNetworkInterface"
              Resource: "*"
        - PolicyName: CostExplorerAccess
          PolicyDocument:
            Statement:
              Effect: Allow
              Action:
                - "ce:*"
              Resource: "*"
        - PolicyName: AssumeCostAnalyserDelegatedAccessRole
          PolicyDocument:
            Statement:
              Effect: Allow
              Action:
                - "sts:AssumeRole"
              Resource: "arn:aws:iam::<ACCCOUNT-B>:role/DelegatedAccessRole"
Run Code Online (Sandbox Code Playgroud)

在账户 B 中(SQS 队列所在的位置)

角色

Resources:
  DelegatedAccessPolicy:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      ManagedPolicyName: DelegatedAccessPolicy
      Path: /
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - sqs:SendMessage
              - sqs:GetQueueAttributes
              - sqs:GetQueueUrl
              - sqs:ListQueues
            Resource: arn:aws:sqs:eu-central-1:<ACCCOUNT-B>:prod-analyser-queue
  DelegatedAccessRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      RoleName: DelegatedAccessRole
      Path: "/"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref TrustedEntities
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: !Ref ExternalId
      ManagedPolicyArns:
        - { "Fn::GetAtt" : ["DelegatedAccessPolicy", "Arn"]}


Run Code Online (Sandbox Code Playgroud)

质量安全体系


  DataPushQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: prod-analyser-queue
      DelaySeconds: 5
      MaximumMessageSize: 262144
      MessageRetentionPeriod: 345600
      VisibilityTimeout: 600
  DataPushQueuePolicy:
    Type: AWS::SQS::QueuePolicy
    Properties:
      PolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            AWS: 
              - arn:aws:iam::<ACCCOUNT-B>:role/DelegatedAccessRole
          Action:
          - sqs:SendMessage
          - sqs:DeleteMessage
          - sqs:GetQueueAttributes
          - sqs:GetQueueUrl
          - sqs:ListQueues
          - sqs:ReceiveMessage
          - sqs:SetQueueAttributes
          Resource: { "Fn::GetAtt" : ["DataPushQueue", "Arn"]}
      Queues:
        - !Ref DataPushQueue

Run Code Online (Sandbox Code Playgroud)

Joh*_*ein 14

最简洁的方法是:

  • 账户 A 中的 Lambda 函数将消息直接发送到账户 B 中的SQS 队列
  • 账户 A 中的 Lambda 函数需要获得使用SendMessage账户 B 中的 SQS 队列的权限
  • 账户 B 中的 SQS 队列将需要一个允许账户 A 中的 Lambda 函数访问的 SQS 策略

来自Amazon SQS 策略的基本示例

以下示例策略向 AWS 帐号授予对美国东部(俄亥俄)区域中指定的队列的权限111122223333SendMessage444455556666/queue1

{
   "Version": "2012-10-17",
   "Id": "Queue1_Policy_UUID",
   "Statement": [{
      "Sid":"Queue1_SendMessage",
      "Effect": "Allow",
      "Principal": {
         "AWS": [ 
            "111122223333"
         ]
      },
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:us-east-2:444455556666:queue1"
   }]  
}
Run Code Online (Sandbox Code Playgroud)

这比扮演一个角色要容易得多。