web-dev-qa-db-fra.com

Quelle est la bonne façon d'écrire les filtres Boto3 pour utiliser un nom de tag personnalisé?

J'essaie de répertorier les occurrences sur les valeurs de balises de différentes clés de balises Par exemple,> une clé de balise - Environnement, autre clé de balise - Rôle. Mon code est donné ci-dessous:

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)

Après avoir exécuté ce script: python script.py arg1 arg2

Je reçois l'erreur suivante 

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

Cela semble familier, est-ce que je l'ai modifié pour quelqu'un quelque part ;-). En fait, le code que j'ai écrit est dans Rush et n'a pas été testé correctement (et je ne me soucie pas de modifier le formatage de chaîne% et de le remplacer par str.format ()). En fait, l'utilisation du paramètre Filters n'est pas correctement documentée dans AWS. 

Veuillez consulter le blog de Russell Ballestrini Filtrage des ressources AWS avec Boto3 pour en savoir plus sur la méthode correcte de filtres de boto. 

  1. Les filtres acceptent les valeurs de liste et les informations contenues dans la balise doivent être dictées. Ainsi [{}]
  2. La documentation de Boto3 est assez ambiguë sur la façon d'utiliser le nom de balise. Il est déroutant sans exemples quand ils disent que vous pouvez utiliser tag: key. Tant de gens vont juste faire [{"tag:keyname","Values": [""] }] et ça ne marche pas. (En réalité, le code d’origine, je suppose que le développeur sait comment fonctionnent les filtres, je ne modifie donc que la structure). 
  3. En fait, vous DEVEZ spécifier explicitement les paires "Nom" et "Valeurs". Donc, la manière correcte de spécifier le nom de la balise est [{"Name" :"tag:keyname", "Values":[""] }]. C'est délicat.

Donc, la manière correcte de formater un filtre si vous voulez utiliser pour votre exemple 

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

(Mise à jour) Et pour vous assurer que argparse prend la valeur de chaîne, vous appliquez simplement l'argument pour prendre des valeurs de chaîne

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

Dans mon propre script python, j'utilise les éléments suivants:

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