2016-05-18 49 views
6

Sto tentando di elencare le istanze sui valori di tag di chiavi di tag diversi Per esempio> una chiave di tag - Ambiente, altra chiave di tag - Ruolo. Il mio codice è il seguente:Quali sono i modi corretti per scrivere i filtri Boto3 per utilizzare il nome del tag personalizzato?

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) 

Dopo aver eseguito questo script: python script.py arg1 arg2

sto ottenendo seguente errore

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'> 

risposta

9

Questo sembra familiare, ho fatto a modificare questo per qualcuno da qualche parte ;-). In realtà il codice che ho scritto è in fretta e non è stato testato correttamente (e non mi preoccupo di modificare la formattazione di stringa% e sostituirla con str.format()). In effetti, l'utilizzo del parametro Filters non è documentato correttamente in AWS.

Fare riferimento al blog di Russell Ballestrini Filtering AWS resources with Boto3 per ulteriori informazioni sul corretto metodo dei filtri di boto.

  1. I filtri accettano il valore dell'elenco e le informazioni all'interno del tag devono essere dettate. quindi [{}]
  2. La documentazione di Boto3 è piuttosto ambigua su come utilizzare specificare il nome del tag. È confuso senza esempi quando dicono che puoi usare tag: key. Così tante persone si limitano a fare [{"tag:keyname","Values": [""] }] e non funziona. (In realtà il codice di origine presuppongo che lo sviluppatore sappia come funzionano i filtri, quindi modifico solo la struttura).
  3. In realtà, è necessario specificare esplicitamente la coppia "Nome" e "Valori". Quindi il modo corretto per specificare il nome del tag è [{"Name" :"tag:keyname", "Values":[""] }]. È difficile.

Quindi il modo corretto di formattazione a filtri se si desidera utilizzare per il vostro esempio

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

(Update) E per assicurarsi argparse assumere valore di stringa, basta far rispettare l'argomento di prendere valori stringa

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'); 
0

Fissare l'Env e ruolo, come io non sono sicuro che la mia o la risposta di mootmoot funzionerà perché l'Array per i valori expects stringhe.

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