通过 ec2 迭代描述实例 boto3
Iterate thru ec2 describe instance boto3
我正在尝试获取描述实例调用的特定值。因此,例如,如果我想从输出中获取 'Hypervisor' 值或 Ebs 具有 'DeleteOnTermintation' 值。下面是我目前用来进行调用和遍历字典输出的当前代码。
import boto3
import pprint
from datetime import datetime
import json
client = boto3.client('ec2')
filters = [{
'Name': 'tag:Name',
'Values': ['*']
}]
class DatetimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
# Let the base class default method raise the TypeError
return json.JSONEncoder.default(self, obj)
output = json.dumps((client.describe_instances(Filters=filters)), cls=DatetimeEncoder)
pprint.pprint(output)
for v in output:
print v['Hypervisor']
出现此错误:
TypeError: string indices must be integers, not str
使用 pprint 查看输出中的所有可用值。
以下是通过 AWS Command-Line Interface (CLI) 显示信息的方法:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId, Hypervisor, NetworkInterfaces[0].Attachment.DeleteOnTermination]'
这是一些 Python:
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
for r in response['Reservations']:
for i in r['Instances']:
print i['InstanceId'], i['Hypervisor']
for b in i['BlockDeviceMappings']:
print b['Ebs']['DeleteOnTermination']
这是 John 的回答,但针对 Python3
进行了更新
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
for r in response['Reservations']:
for i in r['Instances']:
print(i['InstanceId'], i['Hypervisor'])
for b in i['BlockDeviceMappings']:
print(b['Ebs']['DeleteOnTermination'])
我知道我有点晚了,但我的 2 美分可读性是使用生成器理解 (python 3):
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
block_mappings = (block_mapping
for reservation in response["Reservations"]
for instance in reservation["Instances"]
for block_mapping in instance["BlockDeviceMappings"])
for block_mapping in block_mappings:
print(block_mapping["Ebs"]["DeleteOnTermination"])
您还可以使用 jmespath
,与 awscli --query
标志后面相同的查询引擎,自动获取嵌套结果:
import jmespath
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
print(jmespath.search(
"Reservations[].Instances[].DeviceBlockMappings[].Ebs.DeleteOnTermination",
response
))
或者,如果您需要更多功能,请使用 pyjq
。它的语法与 awscli 中使用的 jmespath 略有不同,但它比它有更多优势。假设您不仅想要 DeviceBlockMappings
,而且还想要保持与它相关的 InstanceId
。在 jmespath
中你不能真正做到这一点,因为无法访问外部结构,只有一个嵌套路径。在 pyjq
你可以这样做:
import pyjq
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
print(pyjq.all(
"{id: .Reservations[].Instances[].InstanceId, d:.Reservations[].Instances[].DeviceBlockMappings[]}",
response
))
这将生成一个设备块映射列表及其相应的 InstanceId,有点像 mongo 的展开操作:
{'id': string, d: {'Ebs': {'DeleteOnTermination': boolean}}}[]
打印(jmespath.search("Reservations[].Instances[].[InstanceId, SubnetId, ImageId, PrivateIpAddress, Tags[*]]",响应))
我正在尝试获取描述实例调用的特定值。因此,例如,如果我想从输出中获取 'Hypervisor' 值或 Ebs 具有 'DeleteOnTermintation' 值。下面是我目前用来进行调用和遍历字典输出的当前代码。
import boto3
import pprint
from datetime import datetime
import json
client = boto3.client('ec2')
filters = [{
'Name': 'tag:Name',
'Values': ['*']
}]
class DatetimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
# Let the base class default method raise the TypeError
return json.JSONEncoder.default(self, obj)
output = json.dumps((client.describe_instances(Filters=filters)), cls=DatetimeEncoder)
pprint.pprint(output)
for v in output:
print v['Hypervisor']
出现此错误:
TypeError: string indices must be integers, not str
使用 pprint 查看输出中的所有可用值。
以下是通过 AWS Command-Line Interface (CLI) 显示信息的方法:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId, Hypervisor, NetworkInterfaces[0].Attachment.DeleteOnTermination]'
这是一些 Python:
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
for r in response['Reservations']:
for i in r['Instances']:
print i['InstanceId'], i['Hypervisor']
for b in i['BlockDeviceMappings']:
print b['Ebs']['DeleteOnTermination']
这是 John 的回答,但针对 Python3
进行了更新import boto3
client = boto3.client('ec2')
response = client.describe_instances()
for r in response['Reservations']:
for i in r['Instances']:
print(i['InstanceId'], i['Hypervisor'])
for b in i['BlockDeviceMappings']:
print(b['Ebs']['DeleteOnTermination'])
我知道我有点晚了,但我的 2 美分可读性是使用生成器理解 (python 3):
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
block_mappings = (block_mapping
for reservation in response["Reservations"]
for instance in reservation["Instances"]
for block_mapping in instance["BlockDeviceMappings"])
for block_mapping in block_mappings:
print(block_mapping["Ebs"]["DeleteOnTermination"])
您还可以使用 jmespath
,与 awscli --query
标志后面相同的查询引擎,自动获取嵌套结果:
import jmespath
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
print(jmespath.search(
"Reservations[].Instances[].DeviceBlockMappings[].Ebs.DeleteOnTermination",
response
))
或者,如果您需要更多功能,请使用 pyjq
。它的语法与 awscli 中使用的 jmespath 略有不同,但它比它有更多优势。假设您不仅想要 DeviceBlockMappings
,而且还想要保持与它相关的 InstanceId
。在 jmespath
中你不能真正做到这一点,因为无法访问外部结构,只有一个嵌套路径。在 pyjq
你可以这样做:
import pyjq
import boto3
client = boto3.client('ec2')
response = client.describe_instances()
print(pyjq.all(
"{id: .Reservations[].Instances[].InstanceId, d:.Reservations[].Instances[].DeviceBlockMappings[]}",
response
))
这将生成一个设备块映射列表及其相应的 InstanceId,有点像 mongo 的展开操作:
{'id': string, d: {'Ebs': {'DeleteOnTermination': boolean}}}[]
打印(jmespath.search("Reservations[].Instances[].[InstanceId, SubnetId, ImageId, PrivateIpAddress, Tags[*]]",响应))