如何在 Cost Explorer 中获取每个存储桶级别的 S3 成本明细?

如何在 Cost Explorer 中获取每个存储桶级别的 S3 成本明细?

看来我可以使用过滤器中的服务级别来获取 S3 的总成本。

不过我想获得每个存储桶级别的成本。

可以在 Cost Explorer 中完成吗?

如果没有,我可以使用 aws cli 获取故障信息吗?

在此处输入图片描述

答案1

我会考虑使用成本分配标签:

https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html https://docs.aws.amazon.com/AmazonS3/latest/dev/CostAllocTagging.html

您需要在计费仪表板下激活成本分配标签,然后添加您想要跟踪的标签(即 billinggroup)。

然后在每个 bucket -> 属性 -> 高级设置 -> 标签下设置一个标签,如 billinggroup: bucketname

您也可以使用 aws cli 执行类似的操作,但我认为它不会那么准确,因为它不会计算所有对象版本和副本的大小,但它可能适用于大致数字:

bucketlist="mybucket1 mybucket2"
echo -e "Bucket\tObjectCount\tTotalSize\n"
for x in ${bucketlist}; do 
    echo -en "$x\t"; aws s3 ls s3://$x --recursive | grep -v -E "(Bucket: |Prefix: |LastWriteTime|^$|--)" | awk 'BEGIN {count=0; total=0}{count++; total+=$3}END{print count"\t"total" ("total/2^30"GB)\t$"(total/2^30)*0.023}'
done

答案2

AWS 在其知识库中涵盖了这一点: https://aws.amazon.com/premiumsupport/knowledge-center/s3-find-bucket-cost/

基本上,您需要为每个存储桶添加一个标签,并将值设置为存储桶名称。然后,您可以使用成本浏览器查找每个存储桶的总成本:

AWS 成本报告的屏幕截图

如果您有很多存储桶,这将非常繁琐且容易出错,因此我编写了一个 Python 脚本来自动执行该任务:

import boto3
from botocore.exceptions import ClientError

s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')

def add_bucket_name_tag_to_all_buckets():
    TAG_NAME = 's3-bucket-name'

    for s3_bucket in s3_resource.buckets.all():
        s3_bucket_name = s3_bucket.name
        print(f'Setting tag "{TAG_NAME}" in "{s3_bucket_name}" to "{s3_bucket_name}"...')

        # Create tag iff there are no tags at all
        bucket_tagging = s3_resource.BucketTagging(s3_bucket_name)
        try:
            tags = bucket_tagging.tag_set # This throws if there are no tags
        except ClientError:
            tags = [{'Key':TAG_NAME, 'Value': s3_bucket_name}]
            bucket_tagging.put(Tagging={'TagSet':tags}) # Use carefully, this overwrites all tags

        # Now append tag if not present
        tags = bucket_tagging.tag_set
        if len([x for x in tags if x['Key'] == TAG_NAME]) == 0: # If tag not found, append it
            tags.append({'Key':TAG_NAME, 'Value': s3_bucket_name})
            bucket_tagging.put(Tagging={'TagSet':tags}) # Use carefully, this overwrites all tags


if __name__ == '__main__':
  add_bucket_name_tag_to_all_buckets()

这将递归遍历您的存储桶并附加一个名为的新标签s3-bucket-name,并将值设置为该存储桶的名称。


如果您不懂 Python,或者不信任从互联网上运行的脚本(!),您可以按照亚马逊的说明手动执行操作,粘贴以下内容:


要检查哪个 Amazon S3 存储桶增加了您的存储成本,请执行以下步骤:

  1. 给每个存储桶添加一个通用标签。

  2. 将标签激活为成本分配标签。

重要提示:所有标签最多可能需要 24 小时才能显示在账单和成本管理控制台中。

  1. 使用 AWS Cost Explorer 为您的标签创建 AWS 成本和使用情况报告。

注意:成本分配标签不会显示您在设置标签之前产生的成本。

解决方案在开始之前,您的 AWS Identity and Access Management (IAM) 策略必须具有执行以下操作的权限:

访问账单和成本管理控制台 执行操作 s3:GetBucketTagging 和 s3:PutBucketTagging 提示:避免使用您的 AWS 账户根用户来执行此解决方案。相反,请使用具有所需权限的 IAM 用户或角色。

为每个存储桶添加通用标签

  1. 打开 Amazon S3 控制台。

  2. 从存储桶列表中,选择您想要跟踪成本的存储桶。

  3. 选择属性视图。

  4. 向下滚动并选择标签。

  5. 选择编辑。

  6. 选择添加标签。

  7. 对于 Key,输入要添加到所有要跟踪成本的存储桶的标签的名称。例如,输入“S3-Bucket-Name”。

  8. 对于值,输入存储桶的名称。

  9. 对您想要跟踪成本的所有存储桶重复步骤 1 到 7。

将标签激活为成本分配标签

  1. 打开账单和成本管理控制台。

  2. 从导航窗格中,选择成本分配标签。

  3. 在搜索栏中,输入您为存储桶创建的标签的名称。例如,输入“S3-Bucket-Name”。

  4. 选择标签。

  5. 选择激活。

使用 AWS Cost Explorer 为标签创建成本报告

  1. 打开账单和成本管理控制台。

  2. 从导航窗格中,选择 Cost Explorer。

  3. 选择启动 Cost Explorer。

  4. 从导航窗格中,选择报告。

  5. 选择新报告。

  6. 对于报告模板,选择成本和使用情况报告,然后选择创建报告。

  7. 在过滤器下,对于服务,选择 S3 (简单存储服务)。然后,选择应用过滤器。

  8. 对于标签,选择您创建的标签。例如,选择 S3-Bucket-Name。然后,检查要跟踪成本的每个存储桶,并选择应用筛选条件。

注意:如果您在筛选列表中没有看到您的标签,则可能是该标签最近才创建并应用于存储桶。请等待 24 小时,然后尝试再次创建报告。

  1. 在高级选项下,确认未选中仅显示未标记的资源。

  2. 从图表顶部选择分组依据,然后选择您创建的标签。

  3. 选择“另存为”。

  4. 输入成本报告的标题。

  5. 选择保存报告。

创建成本报告后,使用该报告查看标有您创建的成本分配标签的每个存储桶的成本。

注意:您可以设置每日或每小时的 AWS 成本和使用情况报告以获取更多 Amazon S3 账单详情。但是,这些报告不会显示谁对您的存储桶发出了请求。要查看对您的存储桶的请求来自何处,请启用对象级日志记录或服务器访问日志记录。要获取有关某些 Amazon S3 账单项目的更多信息,您必须提前启用日志记录。然后,您将获得包含 Amazon S3 请求详情的日志。

答案3

我使用 Python 脚本循环遍历每个标签名为 s3-bucket-name 的存储桶,然后将结果保存到 csv 文件中。

import boto3
import csv
from datetime import datetime, timedelta

# Set up AWS credentials and region
session = boto3.Session(
    aws_access_key_id='YOUR_ACCESS_KEY_ID',
    aws_secret_access_key='YOUR_SECRET_ACCESS_KEY',
    region_name='YOUR_REGION'
)

# Set up S3 client and CloudWatch client
s3 = session.client('s3')
cloudwatch = session.client('cloudwatch')

# Set the date range for the cost report
start_time = datetime.utcnow() - timedelta(days=30)
end_time = datetime.utcnow()

# Set the tag key to filter by
tag_key = 's3_bucket_name'

# Get the S3 bucket names that have the specified tag
bucket_names = []
response = s3.list_buckets()
for bucket in response['Buckets']:
    response = s3.get_bucket_tagging(Bucket=bucket['Name'])
    for tag in response['TagSet']:
        if tag['Key'] == tag_key:
            bucket_names.append(bucket['Name'])

# Get the S3 bucket usage metrics for the specified date range and tag
costs_and_sizes_per_bucket = {}
for bucket_name in bucket_names:
    response = cloudwatch.get_metric_statistics(
        Namespace='AWS/S3',
        MetricName='BucketSizeBytes',
        Dimensions=[{'Name': 'BucketName', 'Value': bucket_name}],
        StartTime=start_time,
        EndTime=end_time,
        Period=86400,
        Statistics=['Average']
    )
    if 'Datapoints' in response:
        for datapoint in response['Datapoints']:
            bucket_size = datapoint['Average'] / 1024 / 1024 / 1024
            cost = datapoint['Average'] * 0.000000001 * 0.023
            costs_and_sizes_per_bucket[bucket_name] = {
                'size': bucket_size,
                'cost': costs_and_sizes_per_bucket.get(bucket_name, {}).get('cost', 0) + cost
            }

# Save the bucket name, size, and cost in a CSV file
with open('s3_costs.csv', mode='w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(['Bucket Name', 'Size (GB)', 'Cost'])
    for bucket_name, data in costs_and_sizes_per_bucket.items():
        size = data['size']
        cost = data['cost']
        writer.writerow([bucket_name, size, cost])

print('CSV file saved successfully!')

相关内容