KeyError:' AvailabilityZone'

时间:2017-08-26 04:38:05

标签: python-2.7 boto3

请帮助我解决此问题:当我尝试运行以下脚本时,它始终会返回此错误: KeyError:' AvailabilityZone'

client.describe_instances(过滤器= [{'姓名':'实例 - 州名','值':['运行',]},],)

另外,我发现响应中没有AvailabilityZone字符串。

示例摘录

import boto3
import collections
ec2 = boto3.resource('ec2')
instances = ec2.instances.filter(
    Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])


running_instances = {}
for instance in instances:
    az = instance.placement['AvailabilityZone']
    os = instance.platform
    instance_type = instance.instance_type
    if os is None:
        os = 'Linux/UNIX'
    else:
        os = 'Windows'
    if az not in running_instances:
        running_instances[az] = {}
    if os not in running_instances[az]:
        running_instances[az][os] = {}
    if instance_type not in running_instances[az][os]:
        running_instances[az][os][instance_type] = 0
    running_instances[az][os][instance_type] += 1

client = boto3.client('ec2')
response = client.describe_reserved_instances(
    Filters=[
        {
            'Name': 'state',
            'Values': [
                'active',
            ]
        }
    ],
)
cnt = collections.Counter()

reserved_instances = {}
for instance in response['ReservedInstances']:
    az = instance['AvailabilityZone']
    os = instance['ProductDescription']
    instance_type = instance['InstanceType']
    instance_count = instance['InstanceCount']
    if az not in reserved_instances:
        reserved_instances[az] = {}
    if os not in reserved_instances[az]:
        reserved_instances[az][os] = {}
    if instance_type not in reserved_instances[az][os]:
        reserved_instances[az][os][instance_type] = 0
    reserved_instances[az][os][instance_type] += instance_count

print("****** Running Instances breakdown *****")
print(running_instances)
print("****** Reserved Instance breakdown *****")
print(reserved_instances)

2 个答案:

答案 0 :(得分:1)

首先,我建议将代码示例直接粘贴到问题中,而不是像上面那样链接到它。如果链接数据消失,将使问题更难理解。

我认为您遇到的问题是,当您循环遍历describe_instances返回的实例时,您假设placement属性将始终包含名为 AvailabilityZone 但是,如果有问题的实例处于已停止状态或已终止但不是真实。

因此,您应该检查以确保展示位置在访问之前具有该属性(例如,如果在instance.placement中为'AvailabilityZone')。

答案 1 :(得分:0)

这是完整的ec2.describe_instances响应结果。整个json dict结构清楚地显示为

# ec2.client.describe_instances() responnse structure
{ 'Reservations':[
   {"Group": [{....}]},  
   {"Instances:[{.....}]} 
   ],
  'NextToken': 'string'
}

ec2.client.describe_reserved_instances是关于您购买的预留实例。保留实例折扣与您开始的实例动态匹配,以小时为单位。所以你永远不会得到像操作系统,实例计数等信息。

# describe_reserved_instances is about reserved instances you purchase
{
    'ReservedInstances': [
        {
            'AvailabilityZone': 'string',
            'Duration': 123,
            'End': datetime(2015, 1, 1),
            'FixedPrice': ...,
            'InstanceCount': 123,
            'InstanceType':  
             ............
        },
    ]
} 

您需要做的是遵循正确的python词典参考。 Python不会将字典转换为点表示法,除非您加载像jsontree(仅在python2中)的模块来转换它们。还有named tuple conversion,但我指出'使用它们。使用简单的dict参考就容易多了。

所以正确的符号引用应该如下所示

result = ec2.instances.filter(
    Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])

for reservation in result['Reservations']:
    for instance in reservation['Instances']:
        az = instance['Placement']['AvailabilityZone']

(更新) 新的AWS管理员/用户会提出问题,为什么describe_instancesdescribe_reserved_intances会显示不同的结果集?

简短的回答是:它们不是一回事。 describe_instances将显示您在系统中创建的实际AWS VM。另一方面,reserved instances不是VM,但实际上是折扣计费机制。因此,您不会看到与其关联的任何VM属性,而是货币信息。只要看到合适的情况,AWS就会应用折扣逻辑,因此您不会看到来自describe_reserved_instances的明确的逐项计费。