如何用Python解析AWS CLI输出,梳理VPC、子网与实例关联关系?
解析AWS CLI JSON输出并梳理资源关联的Python实现技巧
错误原因说明
你遇到的TypeError: list indices must be integers or slices, not str(类型错误:列表索引必须是整数或切片,不能是字符串),核心问题是误将列表对象当作字典来索引。AWS CLI返回的JSON结构中,多数资源(如实例、VPC)的顶层数据是数组(比如Reservations、Vpcs),如果跳过数组遍历直接用字典键值索引,就会触发该错误。
通用前置操作
先将AWS CLI输出保存为JSON文件(或直接在Python中调用CLI获取数据):
# 保存VPC数据 aws ec2 describe-vpcs > vpcs.json # 保存子网数据 aws ec2 describe-subnets > subnets.json # 保存实例数据 aws ec2 describe-instances > instances.json
各资源解析实现
1. VPC:提取名称与CIDR范围
describe-vpcs返回的顶层字段Vpcs是数组,每个元素为单个VPC的字典数据,需从Tags中提取名称标签,配合CidrBlock字段输出。
import json with open('vpcs.json', 'r') as f: vpc_data = json.load(f) for vpc in vpc_data['Vpcs']: # 快速提取Name标签,无标签时显示默认值 vpc_name = next((tag['Value'] for tag in vpc['Tags'] if tag['Key'] == 'Name'), '未命名VPC') cidr_block = vpc['CidrBlock'] print(f"VPC名称: {vpc_name}, CIDR范围: {cidr_block}")
2. 子网:提取名称、CIDR及所属VPC
describe-subnets的Subnets数组中,每个子网包含CidrBlock、VpcId字段,同样从Tags中提取名称。
import json with open('subnets.json', 'r') as f: subnet_data = json.load(f) for subnet in subnet_data['Subnets']: subnet_name = next((tag['Value'] for tag in subnet['Tags'] if tag['Key'] == 'Name'), '未命名子网') cidr_block = subnet['CidrBlock'] vpc_id = subnet['VpcId'] print(f"子网名称: {subnet_name}, CIDR范围: {cidr_block}, 所属VPC: {vpc_id}")
3. 实例:提取实例信息及所属VPC、子网
describe-instances结构最复杂:顶层是Reservations数组,每个Reservation下嵌套Instances数组(单个实例数据)。必须先遍历外层数组,再访问内层实例字典,这也是你之前出错的核心点。
import json with open('instances.json', 'r') as f: instance_data = json.load(f) # 先遍历Reservations数组,再遍历每个Reservation下的Instances数组 for reservation in instance_data['Reservations']: for instance in reservation['Instances']: instance_name = next((tag['Value'] for tag in instance['Tags'] if tag['Key'] == 'Name'), '未命名实例') instance_id = instance['InstanceId'] vpc_id = instance['VpcId'] subnet_id = instance['SubnetId'] print(f"实例ID: {instance_id}, 实例名称: {instance_name}, 所属VPC: {vpc_id}, 所属子网: {subnet_id}")
进阶技巧
- 直接在Python中调用AWS CLI
无需提前保存JSON文件,用subprocess模块直接获取输出并解析:
import json import subprocess # 获取实例数据 result = subprocess.run(['aws', 'ec2', 'describe-instances'], capture_output=True, text=True) instance_data = json.loads(result.stdout) # 后续解析逻辑与之前一致
- Bash/Zsh直接过滤输出
如果无需Python处理,可在调用AWS CLI时用--query参数提前过滤冗余数据,直接输出结构化结果:
# 查看VPC名称与CIDR aws ec2 describe-vpcs --query 'Vpcs[*].{Name: Tags[?Key==`Name`].Value|[0], CidrBlock: CidrBlock}' --output table # 查看子网名称、CIDR及所属VPC aws ec2 describe-subnets --query 'Subnets[*].{Name: Tags[?Key==`Name`].Value|[0], CidrBlock: CidrBlock, VpcId: VpcId}' --output table
- 导出为CSV格式
如需将数据导出到表格工具,用Python的csv模块实现:
import csv import json with open('instances.json', 'r') as f, open('instance_relations.csv', 'w', newline='') as csv_file: writer = csv.writer(csv_file) # 写入表头 writer.writerow(['实例ID', '实例名称', 'VPC ID', '子网ID']) instance_data = json.load(f) for reservation in instance_data['Reservations']: for instance in reservation['Instances']: instance_name = next((tag['Value'] for tag in instance['Tags'] if tag['Key'] == 'Name'), '未命名实例') writer.writerow([instance['InstanceId'], instance_name, instance['VpcId'], instance['SubnetId']])
内容的提问来源于stack exchange,提问作者kubbs
相关产品推荐
相关产品推荐

