首页 > 解决方案 > AWS 账单报告 S3 存储桶向另一个账户授予读取权限

问题描述

因此,正如标题所示,这是我设法找到的一个非常具体的错误。我们有一个帐户来保存所有计费数据,然后将其作为每小时报告存储到 S3 存储桶中。

然而,我们有另一个账户,该账户有一个 EC2 实例,我们想授予 GetObject 对我们的计费桶的权限。但是我无法这样做,是因为 AWS CloudWatch 在将报告上传到 S3 时没有将 acl 设置为 bucket-owner-full-control 吗?我不知道为什么会这样。

fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

这是我尝试hourly-Manifest.json使用我的 EC2 实例的 AWS-CLI 从计费存储桶中复制对象时出现的错误。

权限从 billing-account 设置如下,其中 Principal 是第二个帐户根。

{
      "Sid": "ClaudiaReadOnly",
      "Effect": "Allow",
      "Principal": {
          "AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
      },
      "Action": [
        "s3:Get*",
        "s3:List*"
      ],
      "Resource": [
        "arn:aws:s3:::billing-bucket",
        "arn:aws:s3:::billing-bucket/billing/*"
      ]
}

第二个账户使用 CloudFormation 模板向 EC2 实例授予权限,同样具有相同的 Get* 和 List* 权限。

如果我们直接从控制台为第二个账户设置单个对象的读取权限,我们可以使用 EC2 实例的 AWS-CLI 复制它。但是对于每个其他对象,我们都会得到相同的 403 错误。

调试这个问题非常令人沮丧,我希望 AWS 关于这个问题没有更好的信息......

标签: amazon-web-servicesamazon-s3

解决方案


这里的问题是不同的账户(AWS Billing)在您的计费存储桶中创建您的计费报告,这会将您带入 S3 对象 ACL 的阴暗世界 - 请参阅https://docs.aws.amazon.com/AmazonS3/latest /dev/acl-overview.html

如果您从计费账户访问 S3 存储桶,则不会有问题,因为计费账户是存储桶所有者并且始终被授予访问权限,但是对于其他账户,授予访问权限的唯一方法是写入器(AWS计费)在副本上设置适当的 ACL(这不会发生),或追溯修改 ACL。

这是为计费报告创建的默认对象 ACL:

$ aws s3api get-object-acl --bucket my-billing-bucket --key reports/xxx/xxx.json
{
    "Owner": {
        "DisplayName": "aws-billpresentation+artifact-storage",
        "ID": "aaaaaaaaaa"
    },
    "Grants": [
        {
            "Grantee": {
                "DisplayName": "aws-billpresentation+artifact-storage",
                "ID": "aaaaaaaaaa",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        },
        {
            "Grantee": {
                "DisplayName": "mybilling",
                "ID": "xxxxxxxxxxx",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        }
    ]
}

在上面的示例中,aws-billpresentation+artifact-storage 是编写您的报告的 AWS 计费账户的名称,而 mybiling 是您的存储桶所在的计费账户的名称。

如果您想授予另一个帐户的读取权限,则需要找出该帐户的规范 ID,然后添加 READ 授权,对每个文件重复此操作。例如:

aws s3api put-object-acl --bucket my-billing-bucket --key reports/xxx/xxx.json --access-control-policy '{
 "Owner": {
     "DisplayName": "aws-billpresentation+artifact-storage",
     "ID": "aaaaaaaa"
 },
 "Grants": [
     {
         "Grantee": {
             "DisplayName": "aws-billpresentation+artifact-storage",
             "ID": "aaaaaaaa",
             "Type": "CanonicalUser"
         },
         "Permission": "FULL_CONTROL"
     },
     {
         "Grantee": {
             "DisplayName": "mybilling",
             "ID": "xxxxxxxx",
             "Type": "CanonicalUser"
         },
         "Permission": "FULL_CONTROL"
     },
     {
         "Grantee": {
             "DisplayName": "myotheraccount",
             "ID": "yyyyyyyy",
             "Type": "CanonicalUser"
         },
         "Permission": "READ"
     }
   ]
}'

最简单的选择是将报告发布到您要实际处理报告的帐户中,这样可以避免所有 S3 对象 ACL 问题。


推荐阅读