如何使用Boto3获取指定时间点的EBS卷总容量?
获取指定时间点的EBS卷总容量
describe_volumes API只能返回当前存在的EBS卷的最新状态,无法回溯历史时间点的卷容量(包括已删除的卷或扩容前的卷大小)。要实现这个需求,需要借助AWS的配置或事件追踪服务,以下是两种可行方案:
方案1:利用AWS Config追踪资源配置历史
AWS Config会持续记录EBS卷的配置变更(创建、扩容、删除等),通过查询配置历史可以直接获取指定时间点的卷状态快照。
前置条件
目标AWS账户已启用AWS Config,且已配置记录AWS::EC2::Volume资源类型。
代码实现
import boto3 from datetime import datetime def get_ebs_total_size_at_time(target_date_str, account): config_client = boto3.client('configservice', account=account) target_date = datetime.strptime(target_date_str, '%Y-%m-%d').replace(hour=23, minute=59, second=59) total_size = 0 next_token = None # 查询目标时间点仍存在的卷 while True: params = { 'resourceType': 'AWS::EC2::Volume', 'configurationItemStatus': 'ResourceDiscovered', 'timeWindow': { 'startTime': target_date.replace(hour=0, minute=0, second=0), 'endTime': target_date } } if next_token: params['nextToken'] = next_token response = config_client.get_resource_config_history(**params) for item in response.get('configurationItems', []): volume_config = eval(item['configuration']) total_size += volume_config['size'] next_token = response.get('nextToken') if not next_token: break # 查询目标时间点存在但后续被删除的卷 next_token_delete = None while True: delete_params = { 'resourceType': 'AWS::EC2::Volume', 'configurationItemStatus': 'ResourceDeleted', 'timeWindow': { 'startTime': datetime(1970, 1, 1), 'endTime': target_date } } if next_token_delete: delete_params['nextToken'] = next_token_delete delete_response = config_client.get_resource_config_history(**delete_params) for item in delete_response.get('configurationItems', []): deletion_time = datetime.strptime(item['configurationItemStatusChangedTime'], '%Y-%m-%dT%H:%M:%S.%fZ') if deletion_time > target_date: volume_config = eval(item['configuration']) total_size += volume_config['size'] next_token_delete = delete_response.get('nextToken') if not next_token_delete: break return total_size # 使用示例 total_capacity = get_ebs_total_size_at_time('2022-01-01', 'your-account-id') print(f"2022-01-01的EBS卷总容量:{total_capacity} GiB")
方案2:利用CloudTrail追踪事件历史
CloudTrail会记录所有EBS相关API操作(CreateVolume/ModifyVolume/DeleteVolume),通过梳理这些事件可以重构指定时间点的卷状态和容量。
前置条件
目标AWS账户已启用CloudTrail,且事件保留期限覆盖目标时间点(默认90天,可延长至多年)。
代码实现
import boto3 from datetime import datetime def get_ebs_total_size_via_cloudtrail(target_date_str, account): cloudtrail_client = boto3.client('cloudtrail', account=account) target_date = datetime.strptime(target_date_str, '%Y-%m-%d') volume_sizes = {} deleted_volumes = set() # 封装事件查询逻辑 def query_events(event_name): next_token = None while True: params = { 'LookupAttributes': [{'AttributeKey': 'EventName', 'AttributeValue': event_name}], 'StartTime': datetime(2006, 1, 1), 'EndTime': target_date, 'MaxResults': 50 } if next_token: params['NextToken'] = next_token response = cloudtrail_client.lookup_events(**params) yield from response['Events'] next_token = response.get('NextToken') if not next_token: break # 记录所有创建的卷初始容量 for event in query_events('CreateVolume'): event_data = eval(event['CloudTrailEvent']) volume_id = event_data['responseElements']['volumeId'] volume_sizes[volume_id] = event_data['responseElements']['size'] # 更新扩容后的卷容量 for event in query_events('ModifyVolume'): event_data = eval(event['CloudTrailEvent']) volume_id = event_data['requestParameters']['volumeId'] volume_sizes[volume_id] = event_data['responseElements']['volumeModification']['targetSize'] # 记录目标时间点前已删除的卷 for event in query_events('DeleteVolume'): event_data = eval(event['CloudTrailEvent']) deleted_volumes.add(event_data['requestParameters']['volumeId']) # 计算总容量(排除已删除的卷) return sum(size for vol_id, size in volume_sizes.items() if vol_id not in deleted_volumes) # 使用示例 total_capacity = get_ebs_total_size_via_cloudtrail('2022-01-01', 'your-account-id') print(f"2022-01-01的EBS卷总容量:{total_capacity} GiB")
注意事项
- 权限要求:执行代码的IAM角色需具备
configservice:GetResourceConfigHistory(方案1)或cloudtrail:LookupEvents(方案2)权限。 - 数据保留:若目标时间点超出Config/CloudTrail的事件保留期限,将无法获取历史数据。
- 方案选择:Config更适合直接获取资源快照,无需手动梳理事件;CloudTrail灵活性更高,但需处理事件顺序和状态变更逻辑。
内容的提问来源于stack exchange,提问作者Yasen El Makioui
相关产品推荐
相关产品推荐

