如何授予将消息发送到另一个AWS账户中的SQS队列的权限?

时间:2020-06-04 17:05:25

标签: python amazon-iam amazon-sqs serverless-framework

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

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

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

我正在使用无服务器框架,并且需要在交叉帐户角色中使用 ExternalId

我所做的:

在帐户A(执行Lambda函数)中

下面的功能是使用无服务器框架部署的:

  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

角色

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"

在帐户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"]}


SQS


  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

1 个答案:

答案 0 :(得分:2)

最干净的方法不是在帐户B中创建IAM角色,而是:

  • 帐户A中的Lambda函数将邮件直接发送到帐户B中的SQS队列
  • 帐户A中的Lambda函数将需要权限才能使用SendMessage进入帐户B中的SQS队列
  • 帐户B中的SQS队列将需要一个SQS策略,该策略允许帐户A中的Lambda函数进行访问

来自Basic examples of Amazon SQS policies

以下示例策略为位于美国东部(俄亥俄州)的名为111122223333的队列授予AWS帐号SendMessage的{​​{1}}权限:

444455556666/queue1

这比承担角色要容易得多。