amazon-s3 - 如何正确设置 IAM 执行角色和存储桶策略以将 lambda 写入公共(public)读取 S3 存储桶?

标签 amazon-s3 aws-cloudformation amazon-iam serverless-framework

就上下文而言,我正在使用无服务器框架,因此发生了一些事情:

  • 角色是使用一些附加策略创建的,并且 lambda 函数将其分配为执行角色。 S3 策略是(列出更多相关的策略):
    • ListBucket 将存储桶 ARN 作为资源
    • GetObjectPutObject DeleteObjet 到存储桶 ARN 作为以 /* 为前缀的资源
  • 我使用 Cloudformation 资源语法创建存储桶,并设置了公共(public)读取策略,以便将其用作静态网站主机。
  • 我还在 S3 存储桶策略中添加了另一个策略语句,我在其中分配写入操作并将执行角色 ARN 设置为主体。

我得到以下 iamRoleStatements 部分:

- Effect: "Allow"
  Action:
    - "s3:ListBucket"
  Resource:
    - Fn::Join:
        - ""
        - - "arn:aws:s3:::"
          - Ref: StaticSiteBucket
- Effect: "Allow"
  Action:
    - "s3:GetObject"
    - "s3:PutObject"
    - "s3:DeleteObject"
    - "s3:GetObjectVersionTagging"
    - "s3:PutObjectVersionTagging"
  Resource:
    - Fn::Join:
        - ""
        - - "arn:aws:s3:::"
          - Ref: StaticSiteBucket
          - "/*"

我实际上可以确认它为生成的角色生成以下策略:

        {
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name-here"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:GetObjectVersionTagging",
                "s3:PutObjectVersionTagging"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name-here/*"
            ],
            "Effect": "Allow"
        }

有了这个,我运行 lambda 函数来对该存储桶执行 putObject 。收到“访问被拒绝错误”,所以我想如果存储桶本身需要允许写入怎么办,所以我在存储桶策略中包含了一条写入语句:

StaticSiteBucket:
  Type: AWS::S3::Bucket
  Properties:
    AccessControl: PublicRead
    BucketName: ${self:service}-static-site-${self:provider.stage}
    WebsiteConfiguration:
      IndexDocument: index.html
StaticSiteBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket:
      Ref: StaticSiteBucket
    PolicyDocument:
      Statement:
        - Sid: PublicReadGetObject
          Effect: Allow
          Principal: "*"
          Action:
          - s3:GetObject
          Resource:
            Fn::Join: [
              "", [
                "arn:aws:s3:::",
                {
                  "Ref": "StaticSiteBucket"
                },
                "/*"
              ]
            ]
        - Sid: AllowLambdaRoleWrite
          Effect: Allow
          Action:
            - "s3:GetObject"
            - "s3:PutObject"
            - "s3:DeleteObject"
            - "s3:GetObjectVersionTagging"
            - "s3:PutObjectVersionTagging"
          Principal:
            AWS:
              - Fn::GetAtt: [ IamRoleLambdaExecution, Arn ]
          Resource:
            Fn::Join:
              - ""
              - - "arn:aws:s3:::"
                - Ref: StaticSiteBucket
                - "/*"

这会在 S3 存储桶中生成以下策略:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket-name-here/*"
        },
        {
            "Sid": "AllowLambdaRoleWrite",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<role-arn>"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:GetObjectVersionTagging",
                "s3:PutObjectVersionTagging"
            ],
            "Resource": "arn:aws:s3:::bucket-name-here/*"
        }
    ]
}

所以,简而言之,我尝试过:

  • 允许角色具有写入权限,但运气不佳
  • 从存储桶策略向该角色附加写入权限,但不成功

我错过了什么?

最佳答案

所以就我而言,我缺少的是:

  • 我必须包含 getObjectTaggingputObjectTagging 操作。

对于任何有类似问题的人。请阅读下面的内容!

从教训中学习(我实际上花了一天半的时间在这上面)并意识到 Stackoverflow 是经验和知识的宝库。

我想指出:

  • 确定您的代码正在执行哪些 API 操作,然后转到文档并进行检查。一些操作act on buckets而其他则在 objects
  • 就我而言,我可以将任何其他政策声明放入存储桶中,换句话说,
  • 执行角色是获得权力的角色。
  • 我无法实现这一点,但如果有办法获得更明确的错误日志(至少在 aws-sdk 节点的库上),将节省大量时间。堆栈跟踪还不够。欢迎提出建议。

这就是我的 StaticSiteBucket 资源声明现在的样子:

- Effect: "Allow"
  Action:
    - "s3:ListBucket"
  Resource:
    - Fn::Join:
        - ""
        - - "arn:aws:s3:::"
          - Ref: StaticSiteBucket
- Effect: "Allow"
  Action:
    - "s3:GetObject"
    - "s3:PutObject"
    - "s3:DeleteObject"
    - "s3:GetObjectTagging"
    - "s3:PutObjectTagging"
  Resource:
    - Fn::Join:
        - ""
        - - "arn:aws:s3:::"
          - Ref: StaticSiteBucket
          - "/*"

关于amazon-s3 - 如何正确设置 IAM 执行角色和存储桶策略以将 lambda 写入公共(public)读取 S3 存储桶?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56088468/

相关文章:

python - 在 python 中从 S3 加载 npy 文件

java - 与 csv 文件相比,将 mysql 表转换为 spark 数据集非常慢

powershell - 在 CloudFormation 模板中运行 PowerShell 命令

amazon-web-services - 参数验证失败: parameter value for parameter name PublicSubnetAz does not exist

amazon-web-services - Terraform - 具有编程访问权限的 AWS IAM 用户

meteor - meteor ,浏览器策略,HTTP连接到S3的502网关错误

linux - 在 dokku、OS 和 S3 之间设置时区

amazon-web-services - 数据库实例和EC2安全组位于不同的VPC,cloudFormation错误

amazon-web-services - 仅允许通过删除 CloudFormation 堆栈来删除 AWS 资源

amazon-web-services - IAM - AWS 中角色身份的目的