it-swarm.com.ru

Как правильно написать фильтры Boto3 для использования имени собственного тега?

Я пытаюсь перечислить экземпляры значений тегов различных ключей тегов Например,> один ключ тега - Среда, другой ключ тега - Роль. Мой код указан ниже:

import argparse
import boto3

AWS_ACCESS_KEY_ID = '<Access Key>'
AWS_SECRET_ACCESS_KEY = '<Secret Key>'

def get_ec2_instances(Env,Role):
    ec2 = boto3.client("ec2", region)
    reservations = ec2.describe_instances(Filters={"tag:environment" :   Env, "tag:role" : Role})
    for reservation in reservations["Reservations"] :
        for instance in reservation["Instances"]:
             print  "%s" % (instance.tags['Name'])

if  __== '__main__':

    regions = ['us-east-1','us-west-1','us-west-2','eu-west-1','sa-east-1',
               'ap-southeast-1','ap-southeast-2','ap-northeast-1']
    parser = argparse.ArgumentParser()
    parser.add_argument('Env', default="environment", help='value for   tag:environment');
    parser.add_argument('Role', default="role", help='value for tag:role');
    args = parser.parse_args()

    for region in regions: get_ec2_instances(args.Env, args.Role)

После запуска этого скрипта: python script.py arg1 arg2

Я получаю следующую ошибку 

Traceback (most recent call last):
  File "script.py", line 27, in <module>
    for region in regions: get_ec2_instances(args.Env, args.Role)
  File "script.py", line 10, in get_ec2_instances
    reservations = ec2.describe_instances(Filters={"tag:environment" :  Env, "tag:role" : Role})
  File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 258, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 524, in _make_api_call
    api_params, operation_model, context=request_context)
  File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 577, in _convert_to_request_dict
    api_params, operation_model)
  File "/usr/local/lib/python2.7/dist-packages/botocore/validate.py", line 270, in serialize_to_request
    raise ParamValidationError(report=report.generate_report())
botocore.exceptions.ParamValidationError: Parameter validation failed:
Invalid type for parameter Filters, value: {'tag:role': 'arg1', 'tag:environment': 'arg2'}, type: <type 'dict'>, valid types: <type 'list'>, <type 'Tuple'>
7
Abhi

Это выглядит знакомо, я где-то модифицировал это для кого-то ;-). На самом деле код, который я написал, написан на языке Rush и не протестирован должным образом (и я не пытаюсь изменить форматирование строки% и заменить его на str.format ()). Фактически, использование параметра Filters не документировано должным образом в AWS. 

Пожалуйста, обратитесь к блогу Рассела Баллстрини Фильтрация ресурсов AWS с помощью Boto3 , чтобы узнать больше о правильном методе фильтров boto. 

  1. Фильтры принимают значение списка, и информация внутри тега должна быть dict. таким образом [{}]
  2. Документация Boto3 довольно неоднозначна относительно того, как использовать указание имени тега. Без примеров сбивает с толку, когда говорят, что вы можете использовать tag: key. Так много людей просто сделают [{"tag:keyname","Values": [""] }], и это не сработает. (На самом деле исходный код, я полагаю, разработчик знает, как работают фильтры, поэтому я просто изменяю только структуру). 
  3. На самом деле, вы ДОЛЖНЫ явно указать пару «Имя» и «Значения». Таким образом, правильный способ указать имя тега - [{"Name" :"tag:keyname", "Values":[""] }]. Это сложно.

Так что правильный способ форматирования фильтров, если вы хотите использовать для своего примера 

filters = [{'Name':'tag:environment', 'Values':[Env]},
           {'Name':'tag:role', 'Values':[Role]}
          ]

(Обновление) И чтобы argparse принимал строковое значение, вы просто приводите аргумент в соответствие строковым значениям.

parser.add_argument('Env', type=str, default="environment",
                    help='value for   tag:environment');
parser.add_argument('Role', type=str,default="role",
                    help='value for tag:role');
13
mootmoot

В моем собственном скрипте Python я использую следующее:

import boto3
ec2client = boto3.client('ec2','us-east-1')
response = ec2client.describe_instances(Filters=[{'Name' : 'instance-state-name','Values' : ['running']}])
2
A Bantly