Только что понял, потому что boto.utils.get_instance_metadata()
возвращает экземпляр <class 'boto.utils.LazyLoadMetadata'>
, а не истинный dict
. Его внутренние структуры dict
также являются членами LazyLoadMetadata
. Для данных, которые могут быть получены лениво, итераторы, предоставляемые этим классом, возвращают только те элементы/значения, которые уже были явно доступны. Поскольку учетные данные, связанные с экземплярами, являются временными, имеет смысл, что они будут получены лениво.
Пример:
>>> import boto.utils
>>> meta_data = boto.utils.get_instance_metadata()
>>> creds = meta_data.get('iam', {}).get('security-credentials', {})
>>> debug_vals = list(creds.iteritems())
>>> debug_vals
[('ROLE_NAME', None)]
>>>
>>> creds # printing the object evaluates/loads the entire 'tree'
{'ROLE_NAME': {u'Code': u'Success', u'LastUpdated': u'2015-10-20T15:19:27Z', u'AccessKeyId': u'AQW...', u'SecretAccessKey': u'LmA...', u'Token': u'AQ...', u'Expiration': u'2015-10-20T21:36:17Z', u'Type': u'AWS-HMAC'}}
>>>
>>>
>>> debug_vals # old instance was already populated, so it won't change
[('ROLE_NAME', None)]
>>>
>>> debug_vals2 = list(creds.iteritems()) # a new call to iteritems gets the fully loaded tree
>>> debug_vals2
[('ROLE_NAME', {u'Code': u'Success', u'LastUpdated': u'2015-10-20T15:19:27Z', u'AccessKeyId': u'AQW...', u'SecretAccessKey': u'LmA...', u'Token': u'AQ...', u'Expiration': u'2015-10-20T21:36:17Z', u'Type': u'AWS-HMAC'}}]
# THE END
Так что, если вы обращаетесь к ним напрямую, вы найдете ожидаемые значения. Если вы перепробовали их, вы могли бы получить сюрпризы.