No se puede ejecutar AWS CLI desde CRON (credenciales)


27

Intentando ejecutar un script de copia de seguridad simple de AWS CLI. Recorre las líneas en un archivo de inclusión, realiza copias de seguridad de esas rutas hasta S3 y volca la salida en un archivo de registro. Cuando ejecuto este comando directamente, se ejecuta sin ningún error. Cuando lo ejecuto a través de CRON, aparece el error "No se pueden ubicar las credenciales" en mi registro de salida.

El script de shell:

AWS_CONFIG_FILE="~/.aws/config"

while read p; do
 /usr/local/bin/aws s3 cp $p s3://PATH/TO/BUCKET --recursive >> /PATH/TO/LOG 2>&1
done </PATH/TO/INCLUDE/include.txt

Solo agregué la línea al archivo de configuración después de que comencé a ver el error, pensando que esto podría solucionarlo (aunque estoy bastante seguro de que es donde AWS se ve por defecto).

El script de Shell se ejecuta como root. Puedo ver el archivo de configuración de AWS en la ubicación especificada. Y todo me parece bien (como dije, funciona bien fuera de CRON).


2
Prueba un camino absoluto hacia ~/.aws/config.
ceejayoz

Definitivamente lo intenté primero (estaba usando /root/.aws/config), pero volví a ~ / después de verlo en otros hilos. Mismo error de cualquier manera.
binaryorganic

2
No es una respuesta directa sino un comentario sobre el uso de las claves API: es una mejor práctica (y mucho más fácil) asignar roles a sus instancias y crear políticas en torno a esos roles, y luego no es necesario que especifique las claves en absoluto, o pídales que miren en texto sin formato en la instancia. Lamentablemente, esto solo se puede especificar en el momento de la creación de la instancia. Por otro lado, para copiar archivos de registro (y copias de seguridad, etc.), eche un vistazo a las herramientas s3cmd, que proporcionan una funcionalidad similar a rsync.
nico

Respuestas:


20

Si funciona cuando lo ejecutas directamente pero no desde cron, probablemente haya algo diferente en el entorno. Puede guardar su entorno de forma interactiva haciendo

set | sort > env.interactive

Y haz lo mismo en tu guión

set | sort > /tmp/env.cron

Y luego diff /tmp/env.cron env.interactivey ver qué importa. Cosas como PATHson los culpables más probables.


44
¡Gracias! Un paso para poder solucionar el problema por mi cuenta es básicamente invaluable. Definitivamente hubo varias diferencias en la variable PATH, y creo que en este caso fue la diferencia en HOME lo que estaba arruinando las cosas. En cuanto a mi problema específico, terminé ejecutando esto desde el archivo cron del usuario, en lugar de / etc / crontab, que resolvió todo de mi parte. ¡Gracias de nuevo!
binaryorganic

Correcto. agregar una PATHvariable correcta ( echo $PATHdirá lo que debería ser) en el script generalmente lo resuelve.
Fr0zenFyr

33

Cuando ejecuta un trabajo desde crontab, su $HOMEvariable de entorno es/

El cliente de Amazon busca

~/.aws/config

o

~/.aws/credentials

Si $HOME= /, entonces el cliente no encontrará esos archivos

Para que funcione, actualice su script para que exporte un directorio de inicio real para $HOME

export HOME=/root

y luego poner una configuración o archivos de credenciales en

/root/.aws/

Esto ayudó, junto con la siguiente corrección de stackoverflow.com/a/26480929/354709 que implicó agregar la ruta absoluta para el comando aws, ya que $ PATH no se configuró correctamente en el usuario raíz.
Dan Smart

2
Esta debería ser la respuesta aceptada.
Madbreaks

6

Pude resolver este problema a través de lo siguiente :

export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_ACCESS_KEY_ID=XXXX
export AWS_SECRET_ACCESS_KEY=YYYY

1
Pero el objetivo principal aws configurees que no tenga que poner credenciales, por ejemplo, en scripts. Vea la respuesta publicada por @chicks para resolver esto correctamente.
Madbreaks

1
No almacene AWS_ACCESS_KEY_IDni AWS_SECRET_ACCESS_KEYvalores en scripts. La primera línea ya debería haber proporcionado esos valores.
AWippler

2

Ponga este código antes de que su línea de comando se ejecute en crontab -e

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Intenté la primera solución con el diff pero nada. El truco para mí fue la variable RUTA.
borracciaBlu

1

Los binarios de la herramienta aws cli se instalan en /usr/local/bin/aws.

El error que tuve es que el usuario cron no pudo acceder /usr/local/bin/awsmientras se ejecutaba; solo puede acceder/usr/bin/

Lo que hice fue crear un enlace /usr/binpara aws con el siguiente comando.

root@gateway:~# ln -s /usr/local/bin/aws /usr/bin/aws

También agregué algunos cambios en mi script; Aquí hay una función de muestra:

starter () {
    echo "
    ==================================================

    Starting Instance

    ==================================================
    "

    /usr/bin/aws ec2 start-instances --instance-ids $instance --region us-east-1

    sleep 30

    echo "Assigning IP Address "

    /usr/bin/aws ec2 associate-address --instance-id $instance  --region us-east-1 --public-ip XX.XX.XX.XX

}

Y la entrada cron:

30 5 * * * sh /usr/local/cron/magentocron.sh

Este método funcionó para mi.


Mansur, su formato de respuesta está completamente roto.
Aldekein

Usar la ruta completa /usr/bin/awses clave para la solución.
Ramratan Gupta

1

Esta línea en el .bashrcarchivo predeterminado para el usuario evitará que los shells no interactivos obtengan el entorno de usuario completo (incluida la variable PATH):

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Comente la línea para permitir $HOME/.bashrcque se ejecute desde un contexto no interactivo.

También tuve que agregar un sourcecomando explícito a mi script de shell para configurar el entorno correctamente:

#!/bin/bash
source $HOME/.bashrc

Vea esta respuesta para obtener información adicional.


1

Todos sabemos que la variable de ruta de entorno $ PATH tiene la ubicación de los archivos binarios. $ PATH de Crontab podría no tener ubicación awscli.

Lo que puedes hacer es encontrar el camino del binario awscli.

# which aws
/usr/local/bin/aws

y agregue la ruta en $ PATH de crontab agregando la siguiente línea al comienzo de su script (después de shebang).

PATH=$PATH:/usr/local/bin/

Esto funcionó para mí!


Tu respuesta funcionó para mí. Rascándome la cabeza por una hora. Gracias amigo
Hussain7

0

Sé que no es la solución perfecta, pero eso funcionó para mí:

export HOME=/home/user
export AWS_CONFIG_FILE="/home/user/.aws/config"
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=XXX

0

Solo para agregar algo de valor agregado, estaba teniendo problemas con la nueva versión de bash mientras usaba la awscliherramienta instalada a través de PIP, descubrí que nada funcionaría con esta herramienta con las nuevas versiones de bash.

Pude resolver instalando aws-apitools-ec2 esto se puede instalar por

yum install -y aws-apitools-ec2 

Adjunto su guía para más referencia.

http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ec2-clt.pdf


en ubuntu 16.04 no pude encontrar el paquete.
borracciaBlu

0

Tuve el mismo problema, pero después de eliminar la redirección stderr de mi entrada cron (2>@1 ), vi aws: command not founden el registro.

Esto se debe a que AWS cli se instaló en la carpeta de inicio del usuario y agregué una línea a mi usuario .bash_profilepara agregar la ruta de AWS cli a $PATH. Curiosamente, esta es la forma en que la documentación de instalación de AWS cli le indica que lo instale. Pero el usuario .bash_profileno se utiliza cuando se ejecuta crontab del usuario (al menos no en mi entorno de todos modos).

Así que todo lo que hice para solucionar esto fue asegurarme de que mi script crontab también tuviera el aws cli en su camino. Entonces, debajo del shebang de mi guión, ahora tengo PATH=~/.local/bin:$PATH.


0

Para mí esto hizo el truco:

#!/bin/bash

HOME=/home/ubuntu
AWS_CONFIG_FILE="/home/ubuntu/.aws/config"

aws ec2 describe-instances #or whatever command you need to use.

El usuario predeterminado en las instancias EC2 de hoy es ubuntu, y la carpeta raíz es la carpeta de inicio de ese usuario. Ahí es donde también existe el aws cli.


0

No es el mejor, pero tuve que proporcionar la configuración directamente en mi script shell / bash antes de que los comandos del cliente AWS. me gusta:

#!/bin/bash

export AWS_ACCESS_KEY_ID=<ZZZ>
export AWS_SECRET_ACCESS_KEY=<AAA>
export AWS_DEFAULT_REGION=<BBB>
aws s3 cp ....
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.