7 votes

Quelle est la façon correcte d'écrire les filtres Boto3 pour utiliser le nom de la balise de personnalisation ?

J'essaie de lister les instances sur les valeurs de tag de différentes clés de tag. Par exemple, une clé de tag - Environnement, une autre clé de tag - 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  __name__ == '__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'>

13voto

mootmoot Points 1485

Cela me semble familier, ai-je modifié ceci pour quelqu'un quelque part ;-) . En fait, le code que j'ai écrit est précipité et n'a pas été testé correctement (et je n'ai pas pris la peine de modifier le formatage de la 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 Filtrer les ressources AWS avec Boto3 pour en savoir plus sur la méthode correcte des filtres boto.

  1. Les filtres acceptent une liste de valeurs, et l'information à l'intérieur de la balise doit être un dict. ainsi [{}]
  2. La documentation de Boto3 est assez ambiguë sur la façon de spécifier le nom de la balise. Elle est confuse sans exemples quand elle dit que vous pouvez utiliser tag:key. De nombreuses personnes se contentent de faire [{"tag:keyname","Values": [""] }] et ça ne marche pas. (En fait, le code d'origine, je suppose que le développeur sait comment les filtres fonctionnent, donc je ne fais que modifier la structure).
  3. En fait, vous DEVEZ spécifier explicitement la paire "Nom" et "Valeurs". La façon correcte de spécifier le nom d'une balise est donc [{"Name" :"tag:keyname", "Values":[""] }] . C'est délicat.

Donc la façon 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 s'assurer que argparse prend une valeur de chaîne, il suffit d'imposer à l'argument de 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');

1voto

A Bantly Points 24

Dans mon propre script python, j'utilise ce qui suit :

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

-1voto

Zeretil Points 127

Corrigez l'Env et le Role, car je ne suis pas sûr que ma réponse ou celle de mootmoot fonctionnera car le Array for Values s'attend à ce que ficelles.

reservervations = ec2.describe_instances(
        Filters=[
           {'Name': 'tag:environment', 'Values': ['%s'], 'Name': 'tag:role', 'Values': ['%s']} % (Env, Role),
        ]]
    ).get(
        'Reservations', []
    )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X