Python boto3无法获取EC2 block_device_mapping属性值问题咨询
问题根因
你拿不到块设备相关属性是三个常见错误导致的:
- 属性名拼写错误:boto3 EC2实例资源的块设备属性是复数形式
block_device_mappings,你写的单数block_device_mapping根本不存在,调用会直接抛AttributeError。 - 数据结构理解错误:
block_device_mappings返回值是字典构成的列表,不是单个可直接点取属性的嵌套对象——一个EC2实例可以挂载多块块设备(根盘+多块数据盘),每个列表元素对应一块盘的配置,不能直接链式调用.device_name这类写法。另外你要取的卷状态、卷ID字段不在块设备映射的顶层,是嵌套在Ebs子字典里的。 - 注释里的写法本身有语法错误:你给属性名外面套了反引号,真放开注释运行会直接触发Python语法错误。
修正方案
如果要导出块设备信息,建议按「单实例单块盘一行」的逻辑写CSV,避免一个单元格塞多块盘信息导致后续无法统计。修正后的完整代码如下:
import boto3 import csv # 初始化EC2客户端获取所有区域 ec2_cli = boto3.client(service_name='ec2') aws_regions = [region['RegionName'] for region in ec2_cli.describe_regions()['Regions']] # 打开CSV文件,补全块设备相关表头 with open('ec2_inventory.csv', 'w', newline='', encoding='utf-8') as f: data_obj = csv.writer(f) data_obj.writerow([ "S.no", "InstanceID", "ImageID", "Instance Lifecycle", "Instance Type", "Private DNS Name", "Private IP Address", "Root Device Name", "Root Device Type", "VPC ID", "Block Device Name", "EBS Volume ID", "Volume Attach Status", "Delete On Termination" ]) count = 1 for region in aws_regions: ec2_resource = boto3.resource(service_name='ec2', region_name=region) for inst in ec2_resource.instances.all(): # 遍历实例挂载的所有块设备,单块盘写一行 for bd in inst.block_device_mappings: ebs_info = bd.get('Ebs', {}) data_obj.writerow([ count, inst.instance_id, inst.image_id, inst.instance_lifecycle if inst.instance_lifecycle else 'on-demand', inst.instance_type, inst.private_dns_name, inst.private_ip_address, inst.root_device_name, inst.root_device_type, inst.vpc_id, bd['DeviceName'], ebs_info.get('VolumeId', 'N/A'), ebs_info.get('Status', 'N/A'), ebs_info.get('DeleteOnTermination', 'N/A') ]) count += 1
注意事项
- 按需实例的
instance_lifecycle字段返回空值,代码里做了兼容标记为on-demand,Spot实例会正常返回spot标识。 - 部分实例挂载的本地实例存储盘没有EBS相关字段,代码里做了空值兼容,不会抛出KeyError。
- 如果需要把同一个实例的所有块设备信息合并到同一个单元格,可以把遍历块设备的逻辑改成拼接字符串后再写入单行即可。
内容的提问来源于stack exchange,提问作者Shubham Mishra
相关产品推荐
相关产品推荐

