it-swarm.com.de

Wie schreibt man Boto3-Filter so, dass er den benutzerdefinierten Tagnamen verwendet?

Ich versuche, die Instanzen auf Tag-Werten verschiedener Tag-Schlüssel aufzulisten. Für zB> einen Tag-Schlüssel - Umgebung, anderer Tag-Schlüssel - Rolle Mein Code ist unten angegeben:

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)

Nach dem Ausführen dieses Skripts: python script.py arg1 arg2

Ich erhalte einen Fehler 

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

Das kommt mir bekannt vor, habe ich das irgendwo für jemanden modifiziert ;-). Tatsächlich ist der Code, den ich geschrieben habe, in Rush und wurde nicht ordnungsgemäß getestet. Tatsächlich ist die Verwendung des Filters-Parameters in AWS nicht ordnungsgemäß dokumentiert. 

Weitere Informationen zur korrekten Boto-Filter-Methode finden Sie im Russell Ballestrini-Blog Filtern von AWS-Ressourcen mit Boto3

  1. Filter akzeptieren Listenwerte und die Informationen im Tag sollten diktiert werden. also [{}]
  2. Die Boto3-Dokumentation ist ziemlich unklar, wie der Tag-Name anzugeben ist. Es ist verwirrend ohne Beispiele, wenn sie sagen, dass Sie tag: key verwenden können. So viele Leute machen einfach [{"tag:keyname","Values": [""] }] und es funktioniert nicht. (Eigentlich gehe ich davon aus, dass der Origin-Code bekannt ist, dass der Entwickler weiß, wie die Filter funktionieren. Daher ändere ich nur die Struktur.) 
  3. Tatsächlich MÜSSEN Sie das Paar "Name" und "Werte" explizit angeben. Der korrekte Weg, den Tag-Namen anzugeben, ist also [{"Name" :"tag:keyname", "Values":[""] }]. Es ist schwierig.

Die richtige Art, Filter zu formatieren, wenn Sie sie für Ihr Beispiel verwenden möchten 

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

(Update) Um sicherzustellen, dass argparse einen String-Wert verwendet, setzen Sie das Argument einfach durch, um String-Werte zu übernehmen

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

In meinem eigenen Python-Skript verwende ich Folgendes:

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

Obwohl nicht wirklich die Antwort auf Ihre Frage, aber NICHT , [~ # ~] nie [~ # ~] , geben Sie Ihre AWS-Anmeldeinformationen in Ihre Skripte ein. Mit Ihren AWS-Anmeldeinformationen kann jeder Ihr Konto verwenden. Es gibt Bots, die Github und andere Git-Repositories durchsuchen und nach fest codierten AWS-Anmeldeinformationen suchen.

Wenn Sie Ihre Anmeldeinformationen wechseln, wird Ihr gesamter Code beschädigt, oder es fällt Ihnen schwer, alle zu aktualisieren.

Einige Alternativen, anstatt Ihre AWS-Anmeldeinformationen hart zu codieren:

  1. Konfigurieren Sie Ihre ~/.aws/credentials-Datei
  2. Verwenden Sie IAM-Rollen
  3. Verwenden Sie STS, um die Rolle zu übernehmen.

Befolgen Sie die hier beschriebenen Best Practices: Best Practices für die Verwaltung von AWS-Zugriffsschlüsseln

Zur Beantwortung Ihrer Frage finden Sie hier ein Beispiel zum Filtern nach Tags:

argEnv = '<any_string_you_want_to_match_as_a_value_for_a_tag>'
ec2Client = boto3.client('ec2')
response = ec2Client.describe_instances(
    Filters=[
            {
                'Name': 'tag:Projeto',
                'Values': [argEnv]
        }
    ]
)

Stellen Sie sicher, dass 'Wert' eine Liste und keine Zeichenfolge ist. Wenn 'argEnv' beispielsweise eine Zeichenfolge ist, stellen Sie sicher, dass Sie '[]' verwenden, um Ihre Variable einzuschließen.

Wenn Sie dann das Tag: Name konsultieren und dessen Wert abrufen möchten (z. B. den Namen, den Sie für eine bestimmte EC2-Instanz in der Konsole eingerichtet haben):

for reservation in res['Reservations']:
    for instance in reservation['Instances']:
        for tag in instance['Tags']:
            if tag['Key'] == 'Name':
                consoleName = tag['Value']
print(consoleName)

Die Ausgabe ist der Wert des Namens-Tags für jede Ressource. Wie Sie sehen, müssen Sie die Ergebnisse durchlaufen, um das Ergebnis zu erhalten. Sie können die Antwortsyntax überprüfen hier .

0
Paulo Aragão