2017-08-26 137 views
0

請幫我解決這個問題:當我試圖運行下面的腳本,它總是返回該錯誤:KeyError異常: 'AvailabilityZone'KeyError異常: 'AvailabilityZone'

client.describe_instances(過濾器= [ {'Name':'instance-state-name','Values':['running',]},],)

另外,我觀察到響應中沒有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) 

回答

0

這是完整的ec2.describe_instances反應的結果。清楚地顯示爲

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

ec2.client.describe_reserved_instances是你購買的預留實例整個JSON字典結構LS。預留實例折扣與小時基礎上的啓動實例動態匹配。所以你永遠不會得到像操作系統,實例數等信息。

# 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但我ddint'使用它們。只需使用簡單的字典引用就容易得多。

所以正確的符號應參考看起來像這樣

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不是虛擬機,但實際上是打折計費機制。所以你不會看到與它相關的任何虛擬機屬性,而是貨幣信息。 AWS會在適合的時候應用折扣邏輯,所以您不會從describe_reserved_instances中看到可靠的分項計費。

+0

您好,感謝您的幫助... 我想你的建議, 我得到一個錯誤這樣的: 預約在result [「預訂」]: 未定義的變量:導致 當我把它改成: 預約回覆['Reservations']: 我得到: KeyError:'Reservations' –

+0

@IrfanJunaid您是否注意到我改變了您的代碼並將值賦給'result',即'result = ec2.instances。過濾器....'而不是你的代碼'實例= ec2.instance s.filter ...'。順便說一下,您的describe_reserved_instances語法是正確的。 – mootmoot

+0

我還是不明白。試過你的編輯,但仍然是相同的錯誤。這是簡化代碼:[code](https://codeshare.io/2Werq3) –

1

首先,我會建議直接粘貼代碼示例到的問題,而不是如上述連接到它。如果鏈接的數據消失,將會使問題更加難以理解。

我認爲你所看到的問題是,你是通過你的假設placement屬性始終包含一個名爲AvailabilityZone鍵由describe_instances返回的情況下,循環但是如果有問題的實例在停止狀態或終止,將不會成立。

所以,你應該檢查,以確保放置有屬性訪問它之前(例如,如果instance.placement「AvailabilityZone」)。

+0

道歉!將代碼粘貼到問題中。該代碼以前工作正常,但現在它給錯誤。難道是因爲AWS側/ Boto3模塊本身有所改變嗎? –

+0

其實,如何包括完整的堆棧跟蹤。這會有很大的幫助。 – garnaat

+0

這是完整的堆棧跟蹤:[link](https://codeshare.io/5eKqX4) –