¿La forma recomendada de administrar las credenciales con varias cuentas de AWS?

¿Cuál es la mejor manera de administrar varias cuentas de Amazon Web Services (AWS) a través de boto ?

Estoy familiarizado con los archivos de BotoConfig , que estoy usando. Pero cada archivo describe solo una cuenta … y estoy trabajando con más de una organización. Por todas las razones legales, financieras y de seguridad habituales, esas cuentas no se pueden combinar.

Actualmente estoy usando un archivo de configuración de boto por cuenta. P.ej:

  • ~/.boto cuenta predeterminada
  • ~/.boto_clowncollege para la cuenta “clowncollege”
  • ~/.boto_razorassoc para la cuenta “razorassoc”
  • ~/.boto_xyz para la cuenta “xyz”

Entonces algo como:

 def boto_config_path(account=None): """ Given an account name, return the path to the corresponding boto configuration file. If no account given, return the default config file. """ path = '~/.boto' + ('_' + account if account else '') clean_path = os.path.abspath(os.path.expanduser(path)) if os.path.isfile(clean_path): return clean_path else: errmsg = "cannot find boto config file {} for {}".format(clean_path, account) raise ValueError(errmsg) def aws_credentials(account=None): """ Return a tuple of AWS credentials (access key id and secret access key) for the given account. """ try: cfg = INIConfig(open(boto_config_path(account))) return ( cfg.Credentials.aws_access_key_id, cfg.Credentials.aws_secret_access_key ) except Exception: raise conn = EC2Connection(*aws_credentials('razorassoc')) 

¿Bien, mal, o indiferente? ¿Mejoras sugeridas?

En el futuro, boto proporcionará mejores herramientas para ayudarlo a administrar múltiples credenciales, pero en este momento, hay un par de variables de entorno que pueden ayudar.

En primer lugar, puede configurar BOTO_CONFIG para que apunte a un archivo de configuración de boto que desea usar y anulará cualquier archivo de configuración que se encuentre en las ubicaciones normales.

En segundo lugar, puede establecer BOTO_PATH en una lista de lugares separados por dos puntos para buscar un archivo de configuración de boto y buscará allí primero, antes de las ubicaciones de búsqueda normales.

Ninguno de los dos le brinda exactamente lo que desea, pero puede hacer que sea más fácil hacerlo con un poco menos de código.

Si tiene ideas sobre cómo le gustaría que esto funcione en boto, ¡hágamelo saber!

actualizado el 2015-02-06, corregido el 2015-03-19 por la siguiente sección superior

Nuevo intercambio estandarizado de credenciales de boto y AWSCLI (boto> == 2.29.0)

Desde boto 2.29, hay una nueva forma fácil de compartir las credenciales BOTO y AWS CLI tal como lo describe Mike Garnaat en Una forma nueva y estandarizada de administrar credenciales en los SDK de AWS

El objective es:

  1. Permitir compartir credenciales por boto, AWSCLI y posiblemente otros SDK.
  2. mantener toda la configuración en un solo archivo, ubicado en el directorio de perfil de usuario
  3. permitir el uso de perfiles con nombre
  4. mantenerlo lo más simple posible (por ejemplo, evitar conflictos con otros métodos)

Crear archivo de credenciales.

Cree el archivo ~/.aws/credentials (Mac / Linux) o %USERPROFILE%\.aws\credentials (Windwos) de la siguiente manera:

 [default] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr region = eu-west-1 [jekyl] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr region = eu-west-1 [hyde] aws_access_key_id = AxxxZ aws_secret_access_key = CxxxZ region = eu-west-1 

De ahora en adelante, puedes usar un código como este:

Usar perfil predeterminado

 import boto con = boto.connect_s3() 

Utilice el perfil explícito establecido por env de AWS_PROFILE . var

(esta es mi opción favorita para mantener el nombre del perfil fuera del código y aún así darle al desarrollador de mi aplicación la oportunidad de elegir un perfil específico)

 $ export AWS_PROFILE=jekyl 

y mantenga su código tan simple como antes:

 import boto con = boto.connect_s3() 

Especifica perfil explícito en tu código.

 import boto con = boto.connect_s3(profile_name="jekyl") 

Esto es todo lo que normalmente necesitas hacer

La lógica para elegir las credenciales adecuadas se describe en el número 2292 de Boto de la siguiente manera:

El orden de carga de mayor a menor prioridad:

1. Pasado directamente desde el código

  1. Variables de entorno para clave / secreto

  2. Variables de entorno para perfil

  3. Perfil explícito del archivo de credenciales compartidas

  4. Perfil predeterminado del archivo de credenciales compartidas

  5. Perfil explícito del archivo de configuración

  6. Sección de credenciales del archivo de configuración

Un perfil que se pasa desde el código anula cualquier conjunto en una variable de entorno.

Para mantener las cosas limpias y simples, es bueno deshacerse de métodos antiguos, así que elimine cualquier archivo de estilo antiguo (como ~/.aws/config o ~/.boto ), elimine la BOTO_CONFIG ambiental BOTO_CONFIG si está establecida y posiblemente también el archivo, a la que apunta dicha variable.

Y eso es realmente todo para boto> = 2.29.0

Nota: No intente controlar la ubicación del archivo de configuración mediante env.variable (como AWS_CONFIG_FILE ), no funciona como se esperaba.

Usar el perfil de configuración de boto (boto> = 2.24.0)

La siguiente descripción se mantiene aquí solo para aquellos que no pueden actualizarse a boto 2.29.0 o superior

Desde boto 2.24.0 hay una característica llamada profile_name

En su archivo ~/.boto que ya tiene su sección [Credenciales], esto servirá como opción alternativa, y luego las secciones [perfil] que sirven para diferentes perfiles:

 [Credentials] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile jekyl] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile hyde] aws_access_key_id = AxxxZ aws_secret_access_key = CxxxZ 

Luego, cuando creas conexión, usas de esta manera:

 import boto con = boto.connect_s3(profile_name="jekyl") 

Tenga en cuenta que esta función está disponible desde boto 2.24.0.

El tutorial está aquí http://docs.pythonboto.org/en/latest/boto_config_tut.html?highlight=profile

Incluso hay algunas notas sobre el uso de llaveros, pero primero me acostumbraré a estas cosas de perfil, con las que soñaba algunos años.

Compartir archivo de configuración con AWSCLI

AWSCLI se convirtió en una gran herramienta. Como el formato del archivo de configuración es casi el mismo, lo uso de la siguiente manera:

  1. mantener el archivo ~/.aws/config como fue creado por AWSCLI (esta es la ubicación predeterminada)
  2. Copie la sección [default] y cambie su nombre a [Credentials] (dejando los mismos valores dentro).
  3. añadir los perfiles que utilizo
  4. establezca la variable BOTO_CONFIG para que apunte a este archivo ~/.aws/config .

El ~/.boto luego se convertiría en `~ / .aws / config con el siguiente contenido:

 [default] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [Credentials] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile jekyl] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile hyde] aws_access_key_id = AxxxZ aws_secret_access_key = CxxxZ 

De esta manera, se comparte tanto para AWSCLI como para boto incluyendo perfiles.

En lugar de crear un montón de archivos de configuración de boto separados, considere usar el módulo ConfigParser y crear una sección en el archivo .boto para cada una de sus cuentas.

Tu archivo .boto puede verse algo como esto

 #Contents of ~/.boto [clown-college] aws_access_key_id = 123sesamestreet aws_secret_access_key = 678idsaf567ujd [razor-assoc] aws_access_key_id = 437piedmont aws_secret_access_key = 997567ujdfs 

En su código de Python, use ConfigParser para cargar la clave de acceso apropiada para la cuenta que desea usar.

 import ConfigParser from os.path import expanduser ########## BEGIN MAIN ############## # get the path to the user's homedir user_home = expanduser("~") #load their .boto config file config = ConfigParser.ConfigParser() config.read([str(user_home + "/.boto")]) #get the keypair for ClownCollege print config.get('clown-college', 'aws_access_key_id') print config.get('clown-college', 'aws_secret_access_key') print config.get('razor-assoc', 'aws_access_key_id') print config.get('razor-assoc', 'aws_secret_access_key') 

Esto se puede envolver en una función para usar a través de su código boto para configurar fácilmente la cuenta correcta.

A partir de boto> = 2.38, parece que todas las soluciones anteriores pueden causar enormes dolores de cabeza y problemas.

Después de probar esto ampliamente hoy en múltiples plataformas basadas en BSD, parece que la manera más efectiva ahora de administrar las diferentes autenticaciones de perfiles para AWSCLI y py-boto es usar el script interactivo aws configure . Llámelo sin un perfil, y llenará un bloque [predeterminado] para los archivos .aws / config y .aws / credentials, y además configurará cualquier otra magia que necesite para trabajar con su conjunto de herramientas aws ( aunque aún no está claro qué hechizos está lanzando en tu localhost). Llámelo nuevamente con cualquier nombre de perfil, y creará una entrada apropiada.

Tenga en cuenta que esto todavía no funciona para las versiones de boto <2.3.

 aws configure --profile somename AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXXX AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Default region name [None]: us-east-1 Default output format [None]: json 

Tenga en cuenta que, según http://boto.cloudhackers.com/en/latest/boto_config_tut.html , cuando utilizo connect_cloudwatch () para la versión 2.48.0 de Boto, en realidad necesitaba proporcionar el

cloudwatch_region_endpoint

O la conexión aún usaría la misma región que la instancia actual, al enviar datos desde la instancia en EC2 (cuando la instancia está en una región diferente a la que está presionando).

 cat .boto [Boto] cloudwatch_region_name = us-west-2 cloudwatch_region_endpoint = monitoring.us-west-2.amazonaws.com 

Intenté agregar eso al perfil .aws / credentials, pero no pareció funcionar.

 cat .aws/credentials [cloudwatch_centralized_reporting] region = us-west-2 aws_access_key_id = XXX aws_secret_access_key = XXX