¿Cuál es la forma correcta de escribir filtros Boto3 para usar el nombre de etiqueta personalizado?

Estoy intentando enumerar las instancias en valores de tags de diferentes claves de tags Por ejemplo,> una clave de etiqueta – Entorno, otra clave de etiqueta – Rol. Mi código se da a continuación:

import argparse import boto3 AWS_ACCESS_KEY_ID = '' AWS_SECRET_ACCESS_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) 

Después de ejecutar este script: python script.py arg1 arg2

Estoy recibiendo error siguiente

 Traceback (most recent call last): File "script.py", line 27, in  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: , valid types: ,  

Esto parece familiar, lo modifiqué para alguien en algún lugar ;-). En realidad, el código que escribí está apurado y no se ha probado correctamente (y no me molesto en modificar el formato de cadena% y reemplazarlo con str.format ()). De hecho, el uso del parámetro Filtros no está documentado correctamente en AWS.

Consulte el blog de Russell Ballestrini Filtrado de los recursos de AWS con Boto3 para obtener más información sobre el método correcto de los filtros de Boto .

  1. Los filtros aceptan el valor de la lista, y la información dentro de la etiqueta debe ser dict. así [{}]
  2. La documentación de Boto3 es bastante ambigua sobre cómo usar especificar el nombre de la etiqueta. Es confuso sin ejemplos cuando dicen que puedes usar tag: key. Muchas personas simplemente harán [{"tag:keyname","Values": [""] }] y no funcionará. (En realidad, el código de origen supongo que el desarrollador sabe cómo funcionan los filtros, así que solo modifico la estructura).
  3. En realidad, DEBES especificar explícitamente los pares “Nombre” y “Valores”. Entonces, la forma correcta de especificar el nombre de la etiqueta es [{"Name" :"tag:keyname", "Values":[""] }] . Es complicado

Por lo tanto, la forma correcta de formatear los filtros si desea utilizarlos para su ejemplo.

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

(Actualización) Y para asegurarte de que argparse tome el valor de la cadena, simplemente impones el argumento para tomar los valores de la cadena

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

En mi propio script de Python utilizo lo siguiente:

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

Corrija el entorno y el rol, ya que no estoy seguro de que la respuesta de mootmoot o mootmoot funcione porque la matriz de valores espera cadenas.

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