如何使用Boto3导出带EBS卷信息的AWS EC2实例列表到Excel
问题核心原因
- 原代码每匹配到一个卷就调用
result.append(),相当于给每个卷单独新增一行,没有把卷信息追加到对应实例的同一行字典中 - 多个卷的属性没有做标识区分,存储时会被当成同一个字段的多个值,最终挤在同一个单元格
解决方法
处理每个实例时,先构造包含实例基础信息的行字典,再遍历该实例挂载的所有卷,给每个卷的属性加上序号后缀作为独立键存入行字典,所有卷处理完成后再把整行追加到结果列表,即可实现每个实例仅占一行,所有卷属性单独成列。
代码示例(boto3 resource模式,即你当前使用的ec3 = boto3.resource('ec2')场景)
# 遍历每个EC2实例的逻辑中 # 第一步:先填充实例基础信息到行字典 instance_row = { 'ImageId': each['ImageId'], 'InstanceType': each['InstanceType'], 'InstanceId': each['InstanceId'], 'InstanceName': each.get('InstanceName', '') # 你原有需要导出的其他实例字段继续在这里补充 } # 第二步:遍历当前实例挂载的所有EBS卷,按序号加字段 volume_index = 1 for vol in ec3.Instance(each['InstanceId']).volumes.all(): instance_row[f'volume_{volume_index}.id'] = vol.id instance_row[f'volume_{volume_index}.type'] = vol.volume_type instance_row[f'volume_{volume_index}.size'] = f"{vol.size}GB" volume_index += 1 # 第三步:整行信息组装完成后再追加到结果列表,每个实例仅append一次 result.append(instance_row)
代码示例(boto3 client模式,即ec3 = boto3.client('ec2')场景)
如果你初始化的是client类型的EC2对象,改用下面的卷遍历逻辑即可:
volume_index = 1 resp = ec3.describe_volumes(Filters=[ {'Name': 'attachment.instance-id', 'Values': [each['InstanceId']]} ]) for vol in resp['Volumes']: instance_row[f'volume_{volume_index}.id'] = vol['VolumeId'] instance_row[f'volume_{volume_index}.type'] = vol['VolumeType'] instance_row[f'volume_{volume_index}.size'] = f"{vol['Size']}GB" volume_index += 1
注意事项
导出CSV/Excel时,需要把所有可能出现的卷字段(比如最多有5个卷的话,要把volume_1.id到volume_5.size共15个字段)都加入表头列表,避免漏列。
内容的提问来源于stack exchange,提问作者Chakaravarthy Natesan
相关产品推荐
相关产品推荐

