答案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/
基本上,您需要为每个存储桶添加一个标签,并将值设置为存储桶名称。然后,您可以使用成本浏览器查找每个存储桶的总成本:
如果您有很多存储桶,这将非常繁琐且容易出错,因此我编写了一个 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 存储桶增加了您的存储成本,请执行以下步骤:
给每个存储桶添加一个通用标签。
将标签激活为成本分配标签。
重要提示:所有标签最多可能需要 24 小时才能显示在账单和成本管理控制台中。
- 使用 AWS Cost Explorer 为您的标签创建 AWS 成本和使用情况报告。
注意:成本分配标签不会显示您在设置标签之前产生的成本。
解决方案在开始之前,您的 AWS Identity and Access Management (IAM) 策略必须具有执行以下操作的权限:
访问账单和成本管理控制台 执行操作 s3:GetBucketTagging 和 s3:PutBucketTagging 提示:避免使用您的 AWS 账户根用户来执行此解决方案。相反,请使用具有所需权限的 IAM 用户或角色。
为每个存储桶添加通用标签
打开 Amazon S3 控制台。
从存储桶列表中,选择您想要跟踪成本的存储桶。
选择属性视图。
向下滚动并选择标签。
选择编辑。
选择添加标签。
对于 Key,输入要添加到所有要跟踪成本的存储桶的标签的名称。例如,输入“S3-Bucket-Name”。
对于值,输入存储桶的名称。
对您想要跟踪成本的所有存储桶重复步骤 1 到 7。
将标签激活为成本分配标签
打开账单和成本管理控制台。
从导航窗格中,选择成本分配标签。
在搜索栏中,输入您为存储桶创建的标签的名称。例如,输入“S3-Bucket-Name”。
选择标签。
选择激活。
使用 AWS Cost Explorer 为标签创建成本报告
打开账单和成本管理控制台。
从导航窗格中,选择 Cost Explorer。
选择启动 Cost Explorer。
从导航窗格中,选择报告。
选择新报告。
对于报告模板,选择成本和使用情况报告,然后选择创建报告。
在过滤器下,对于服务,选择 S3 (简单存储服务)。然后,选择应用过滤器。
对于标签,选择您创建的标签。例如,选择 S3-Bucket-Name。然后,检查要跟踪成本的每个存储桶,并选择应用筛选条件。
注意:如果您在筛选列表中没有看到您的标签,则可能是该标签最近才创建并应用于存储桶。请等待 24 小时,然后尝试再次创建报告。
在高级选项下,确认未选中仅显示未标记的资源。
从图表顶部选择分组依据,然后选择您创建的标签。
选择“另存为”。
输入成本报告的标题。
选择保存报告。
创建成本报告后,使用该报告查看标有您创建的成本分配标签的每个存储桶的成本。
注意:您可以设置每日或每小时的 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!')