Python 迭代 ec2 描述实例 boto3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38112770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 20:22:23  来源:igfitidea点击:

Iterate thru ec2 describe instance boto3

pythonamazon-ec2

提问by user2040074

I just started working with boto3 and trying to get specific values for a describe instance call. So for example, if I want to get the 'Hypervisor' value or the Ebs has 'DeleteOnTermintation' value from the output. Below is the current code I am currently using to make the call and iterate thru the dictionary output.

我刚开始使用 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']

Getting this error:

收到此错误:

TypeError: string indices must be integers, not str

类型错误:字符串索引必须是整数,而不是 str

Using the pprint to see all the values available from the output.

使用 pprint 查看输出中的所有可用值。

Thanks..

谢谢..

回答by John Rotenstein

Here's how you could display the information via the AWS Command-Line Interface (CLI):

以下是通过AWS 命令​​行界面 (CLI)显示信息的方法:

aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId, Hypervisor, NetworkInterfaces[0].Attachment.DeleteOnTermination]'

Here's some Python:

这是一些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']

回答by ahonnecke

Here's John's answer but updated for Python3

这是约翰的答案,但已针对 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'])  

回答by GChamon

I know I am kinda late to the party, but my 2 cents for readability is to use generator comprehension (python 3):

我知道我参加聚会有点晚了,但我的可读性 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"])

You can also use jmespath, the same query engine behind awscli --queryflag, to get the nested results automatically:

您还可以使用jmespathawscli--query标志后面的相同查询引擎来自动获取嵌套结果:

import jmespath
import boto3

client = boto3.client('ec2')

response = client.describe_instances()
print(jmespath.search(
    "Reservations[].Instances[].DeviceBlockMappings[].Ebs.DeleteOnTermination", 
    response
))

Or, in case you need more power, use pyjq. Its syntax is a little different from jmespath which is used in awscli, but it has more advantages over it. Let's say you want not only the DeviceBlockMappingsbut also to keep to which InstanceIdit is related to. In jmespathyou cant really do this, because there is no access to outer structures, just a single nestes path. Inpyjq` you can do something like this:

或者,如果您需要更多功率,请使用pyjq. 它的语法与 awscli 中使用的 jmespath 略有不同,但比它具有更多优势。假设您不仅希望DeviceBlockMappings而且还希望保持与InstanceId它相关的内容。在jmespath你可以t really do this, because there is no access to outer structures, just a single nestes path. Inpyjq` 你可以做这样的事情:

import pyjq
import boto3

client = boto3.client('ec2')

response = client.describe_instances()
print(pyjq.all(
  "{id: .Reservations[].Instances[].InstanceId, d:.Reservations[].Instances[].DeviceBlockMappings[]}",
  response
))

This will yield a list of device block mappings with their corresponding InstanceId, kind of like a mongo's unwind operation:

这将产生一个设备块映射列表及其对应的 InstanceId,有点像 mongo 的 unwind 操作:

{'id': string, d: {'Ebs': {'DeleteOnTermination': boolean}}}[]

回答by vandam

print (jmespath.search("Reservations[].Instances[].[InstanceId, SubnetId, ImageId, PrivateIpAddress, Tags[*]]", response))

打印 (jmespath.search("Reservations[].Instances[].[InstanceId, SubnetId, ImageId, PrivateIpAddress, Tags[*]]", response))