求Python Boto3代码:批量获取AWS卷ID关联的EC2实例ID与名称
Python Boto3 批量获取AWS卷挂载的EC2实例信息
前置准备
- 安装boto3:
pip install boto3 - 配置AWS凭证:可通过环境变量、
~/.aws/credentials文件或IAM角色(在EC2/ECS等AWS服务上运行时)授权,需具备ec2:DescribeVolumes和ec2:DescribeInstances权限。
代码实现
假设你的卷ID文件名为volume_ids.txt,每行一个卷ID(空行和以#开头的注释行会被自动忽略):
import boto3 from botocore.exceptions import ClientError def load_volume_ids(file_path): """从文本文件加载卷ID,过滤空行和注释""" volume_ids = [] with open(file_path, 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#'): volume_ids.append(line) return volume_ids def get_volume_instance_mapping(ec2_client, volume_ids): """获取卷ID到挂载实例ID的映射""" volume_instance_map = {} try: # describe_volumes一次最多支持100个卷ID,匹配你的需求 response = ec2_client.describe_volumes(VolumeIds=volume_ids) for volume in response['Volumes']: vol_id = volume['VolumeId'] attachments = volume.get('Attachments', []) # 一个卷通常仅挂载到一个实例,取第一个挂载记录 instance_id = attachments[0]['InstanceId'] if attachments else None volume_instance_map[vol_id] = instance_id except ClientError as e: print(f"查询卷信息出错: {e.response['Error']['Message']}") raise return volume_instance_map def get_instance_names(ec2_client, instance_ids): """批量获取实例ID对应的名称标签""" instance_name_map = {} if not instance_ids: return instance_name_map try: response = ec2_client.describe_instances(InstanceIds=instance_ids) for reservation in response['Reservations']: for instance in reservation['Instances']: inst_id = instance['InstanceId'] # 查找Name标签,无标签时显示'无名称' name_tag = next((tag['Value'] for tag in instance.get('Tags', []) if tag['Key'] == 'Name'), '无名称') instance_name_map[inst_id] = name_tag except ClientError as e: print(f"查询实例信息出错: {e.response['Error']['Message']}") raise return instance_name_map if __name__ == '__main__': # 初始化EC2客户端 ec2 = boto3.client('ec2') # 加载卷ID volume_ids = load_volume_ids('volume_ids.txt') if not volume_ids: print("未加载到有效卷ID") exit(1) # 获取卷与实例的映射 vol_instance_map = get_volume_instance_mapping(ec2, volume_ids) # 收集所有已挂载的实例ID valid_instance_ids = [inst_id for inst_id in vol_instance_map.values() if inst_id] # 获取实例名称 inst_name_map = get_instance_names(ec2, valid_instance_ids) # 格式化输出结果 print("卷ID\t\t实例ID\t\t实例名称") print("-" * 60) for vol_id, inst_id in vol_instance_map.items(): if inst_id: inst_name = inst_name_map.get(inst_id, '无名称') print(f"{vol_id}\t{inst_id}\t{inst_name}") else: print(f"{vol_id}\t未挂载\t\t-")
关键点说明
- 批量API调用:利用
describe_volumes和describe_instances的批量查询能力,减少API请求次数,提升处理效率。 - 异常处理:捕获
ClientError并输出具体错误信息,便于排查权限不足或资源不存在的问题。 - 边界场景处理:兼容卷未挂载、实例未设置
Name标签的情况,避免程序崩溃。 - 文件兼容性:自动过滤空行和注释行,适配不同格式的卷ID文件。
内容的提问来源于stack exchange,提问作者Gax
相关产品推荐
相关产品推荐

