2016-05-18 4 views
6

Ich versuche, die Instanzen auf Tag-Werte verschiedener Tag-Schlüssel aufzulisten Für zB> einen Tag-Schlüssel - Umgebung, andere Tag-Schlüssel - Rolle. Mein Code ist unten angegeben:Wie können Boto3-Filter richtig geschrieben werden, um den benutzerdefinierten Tagnamen zu verwenden?

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) 

Nachdem dieses Skript ausgeführt wird: Python script.py arg1 arg2

Ich erhalte Fehler folgende

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

Antwort

9

Dieser vertraut aussieht, habe ich das ändern für jemand irgendwo ;-). Eigentlich ist der Code, den ich geschrieben habe, in Eile und wurde nicht richtig getestet (und ich kümmere mich nicht darum, die Formatierung von% string zu ändern und sie durch str.format() zu ersetzen). Der Filterparameter ist in AWS nicht ordnungsgemäß dokumentiert.

Bitte beziehen Sie sich auf Russell Ballestrini Blog Filtering AWS resources with Boto3, um mehr über korrekte Boto-Filter-Methode zu lernen.

  1. Filter akzeptieren Listenwert, und Informationen innerhalb des Tags sollten dict sein. also [{}}
  2. Boto3 Dokumentation ist ziemlich zweideutig wie Sie den Tag-Namen angeben. Es ist ohne Beispiele verwirrend, wenn Sie sagen, dass Sie tag: key verwenden können. So viele Leute werden nur tun [{"tag:keyname","Values": [""] }] und es funktioniert nicht. (Eigentlich der Ursprungscode Ich nehme an, der Entwickler weiß, wie die Filter funktionieren, also ändere ich nur die Struktur).
  3. Eigentlich müssen Sie explizit "Name" und "Werte" Paar angeben. Der richtige Name für den Tag lautet [{"Name" :"tag:keyname", "Values":[""] }]. Es ist schwierig.

So ist der richtige Weg, um einen Filter der Formatierung, wenn Sie für Ihr Beispiel verwenden mögen

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

(Update) Und um sicherzustellen, dass String-Wert argparse zu nehmen, erzwingen Sie nur das Argument zu nehmen String-Werte

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

Fix die Env und Rolle, wie ich bin nicht sicher, ob meine oder Antwort des mootmoot funktionieren wird, weil das Array für Werte expects Saiten.

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