为什么像 S3 (arn:aws:s3:::) 这样的 IAM 角色声明不适用于 SQS 等其他 AWS 资源?

Why do IAM role statements like for S3 (arn:aws:s3:::) not work for other AWS resources like SQS?

一段时间以来,我已经成功地将 IAM 角色声明放入我的 serverless.yml 以进行 S3 访问,并假设在我添加 SQS 时一切都会以类似的方式工作。我采用了非常简单的 arn:aws:s3::: 并将 s3 替换为 SQS,如下所示:

  iam:
role:
  statements:
    - Effect: 'Allow'
      Action:
        - 's3:ListBucket'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - mahtestbucket
    - Effect: 'Allow'
      Action:
        - 's3:GetObject'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - mahtestbucket
            - '/*'

    - Effect: 'Allow'
      Action:
        - 's3:ListBucket'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - mahfailbucket
    - Effect: 'Allow'
      Action:
        - 's3:PutObject'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - mahfailbucket
            - '/*'
    - Effect: 'Allow'
      Action:
        - 'sqs:SendMessage'
        - 'sqs:GetQueueUrl'
        - 'sqs:GetQueueAttributes'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:sqs:::'
            - mahqueue

这部署没有错误。我可以看到政策声明,但它不起作用。 lambda 函数在尝试访问 SQS 资源时失败。

我决定 post 用我自己的答案来解决这个问题,因为我浪费了几个小时的时间来验证正在创建的策略并确定发生了什么。我相信,由于 S3 通常不包含区域定义,并且存储桶是全局的,因此更简单的规范可行。然而,SQS 和可能的大多数其他资源都需要这些东西。一旦我确定这可能是问题所在,就需要进行一些研究才能使正确的语法起作用:

        - Effect: 'Allow'
      Action:
        - 'sqs:SendMessage'
        - 'sqs:GetQueueUrl'
        - 'sqs:GetQueueAttributes'
        - 'sqs:ListQueues'
      Resource:
        Fn::Join:
          - ''
          - - !Sub 'arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:'
            - mahqueue