【问题标题】:Iterate thru ec2 describe instance boto3遍历 ec2 描述实例 boto3
【发布时间】:2016-11-01 22:32:15
【问题描述】:

我正在尝试获取描述实例调用的特定值。例如,如果我想从输出中获取“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 查看输出中的所有可用值。

【问题讨论】:

    标签: python amazon-ec2 boto3


    【解决方案1】:

    以下是通过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']
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案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"])
        

        您还可以使用 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}}}[]
        

        【讨论】:

          【解决方案4】:

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

          【讨论】:

          • 这真的太少了,不能成为有用的答案。请在此处说明您的建议
          猜你喜欢
          • 1970-01-01
          • 2017-03-16
          • 2018-06-18
          • 2018-09-26
          • 2022-11-03
          • 2017-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多