Impossible d'exécuter AWS CLI à partir de CRON (informations d'identification)

27

Essayer d'exécuter un simple script de sauvegarde AWS CLI. Il parcourt les lignes d'un fichier include, sauvegarde ces chemins jusqu'à S3 et sauvegarde la sortie dans un fichier journal. Lorsque j'exécute cette commande directement, elle s'exécute sans aucune erreur. Lorsque je l'exécute via CRON, j'obtiens une erreur «Impossible de localiser les informations d'identification» dans mon journal de sortie.

Le script 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

Je n'ai ajouté la ligne au fichier de configuration qu'après avoir commencé à voir l'erreur, pensant que cela pourrait la corriger (même si je suis pratiquement sûr que c'est là qu'AWS regarde par défaut).

Le script shell s'exécute en tant que root. Je peux voir le fichier de configuration AWS à l'emplacement spécifié. Et tout me semble bien (comme je l'ai dit, cela fonctionne bien en dehors de CRON).

binaireorganique
la source
2
Essayez un chemin absolu vers ~/.aws/config.
ceejayoz du
Certainement essayé en premier (utilisait /root/.aws/config), mais est revenu à ~ / après l'avoir vu dans d'autres threads. Même erreur de toute façon.
binaryorganic
2
Pas une réponse directe mais un commentaire sur l'utilisation des clés API: il est préférable (et beaucoup plus facile) d'attribuer des rôles à vos instances et de créer des stratégies autour de ces rôles, et vous n'êtes alors pas obligé de spécifier les clés, ou les faire traîner en clair sur l'instance. Malheureusement, cela ne peut être spécifié qu'au moment de la création de l'instance. Soit dit en passant, pour copier les fichiers journaux (et les sauvegardes, etc.), jetez un œil aux outils s3cmd, qui offrent des fonctionnalités similaires à rsync.
nico

Réponses:

20

Si cela fonctionne lorsque vous l'exécutez directement mais pas depuis cron, il y a probablement quelque chose de différent dans l'environnement. Vous pouvez sauvegarder votre environnement de manière interactive en faisant

set | sort > env.interactive

Et faites la même chose dans votre script

set | sort > /tmp/env.cron

Et puis diff /tmp/env.cron env.interactiveet voyez ce qui compte. Des choses comme PATHles coupables les plus probables.

poussins
la source
4
Merci! Une étape vers la résolution du problème par moi-même est fondamentalement inestimable. Il y avait certainement plusieurs différences dans la variable PATH, et je pense que dans ce cas, c'est la différence dans HOME qui a jeté les choses. Quant à mon problème spécifique, j'ai fini par l'exécuter à partir du fichier cron de l'utilisateur, au lieu de / etc / crontab, qui a tout résolu de mon côté. Merci encore!
binaryorganic
Droite. l'ajout d'une PATHvariable correcte ( echo $PATHindiquera ce qu'elle devrait être) dans le script la résout généralement .
Fr0zenFyr
33

Lorsque vous exécutez un travail à partir de crontab, votre $HOME variable d'environnement est/

Le client Amazon recherche soit

~/.aws/config

ou

~/.aws/credentials

Si $HOME= /, le client ne trouvera pas ces fichiers

Pour le faire fonctionner, mettez à jour votre script afin qu'il exporte un véritable répertoire personnel pour $HOME

export HOME=/root

puis mettez une configuration ou des fichiers d'informations d'identification dans

/root/.aws/
Garreth McDaid
la source
Cela a aidé, avec le correctif suivant de stackoverflow.com/a/26480929/354709 qui impliquait l'ajout du chemin absolu pour la commande aws - car $ PATH n'était pas correctement défini dans l'utilisateur root.
Dan Smart
2
Ce devrait être la réponse acceptée.
Madbreaks
6

J'ai pu résoudre ce problème grâce aux éléments suivants :

export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_ACCESS_KEY_ID=XXXX
export AWS_SECRET_ACCESS_KEY=YYYY
Daniel Tronolone
la source
1
Mais le but aws configureest de ne pas avoir à mettre de justificatifs d'identité, par exemple dans des scripts. Voir la réponse publiée par @chicks pour résoudre ce problème correctement.
Madbreaks
1
Ne stockez pas AWS_ACCESS_KEY_IDet AWS_SECRET_ACCESS_KEYvaleurs dans les scripts. La première ligne aurait déjà dû fournir ces valeurs.
AWippler
2

Mettez ce code avant votre ligne de commande à exécuter dans crontab -e

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Roberto Carlos Reyes Fernández
la source
J'ai essayé la première solution avec le diff mais rien. l'astuce pour moi était la variable PATH.
borracciaBlu
1

Les fichiers binaires de l'outil aws cli sont installés sous /usr/local/bin/aws.

L'erreur que j'ai eue est que l'utilisateur cron n'a pas pu accéder /usr/local/bin/aws en cours d'exécution; il ne peut accéder qu'à/usr/bin/

Ce que j'ai fait était de créer un lien /usr/binpour aws avec la commande ci-dessous.

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

J'ai également ajouté quelques changements dans mon script; voici un exemple de fonction:

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

}

Et l'entrée cron:

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

Cette méthode a fonctionné pour moi.

Mansur Ali
la source
Mansur, la mise en forme de votre réponse est complètement cassée.
Aldekein
l'utilisation du chemin complet /usr/bin/awsest la clé de la solution.
Ramratan Gupta
1

Cette ligne dans le .bashrcfichier par défaut de l'utilisateur empêchera les shells non interactifs d'obtenir l'environnement utilisateur complet (y compris la variable PATH):

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

Commentez la ligne pour permettre $HOME/.bashrcson exécution à partir d'un contexte non interactif.

J'ai également dû ajouter une sourcecommande explicite à mon script shell pour configurer correctement l'environnement:

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

Voir cette réponse pour plus d'informations.

Peter Gluck
la source
1

Nous savons tous que la variable de chemin d'environnement $ PATH a l'emplacement des binaires. $ PATH de Crontab peut ne pas avoir d'emplacement awscli.

Ce que vous pouvez faire est de trouver le chemin du binaire awscli.

# which aws
/usr/local/bin/aws

et ajoutez le chemin dans $ PATH de crontab en ajoutant la ligne ci-dessous au début de votre script (après shebang).

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

Cela a fonctionné pour moi !!!

Nijil
la source
Votre réponse a fonctionné pour moi. Se gratter la tête pendant une heure. Merci, mon pote
Hussain7
0

Je sais que ce n'est pas la solution parfaite mais cela a fonctionné pour moi:

export HOME=/home/user
export AWS_CONFIG_FILE="/home/user/.aws/config"
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=XXX
Gustavo
la source
0

Juste pour ajouter de la valeur ajoutée, j'ai eu un problème avec la nouvelle version de bash lors de l'utilisation de l' awsclioutil installé via PIP, j'ai constaté que rien ne fonctionnerait avec cet outil avec les nouvelles versions de bash.

J'ai pu résoudre en installant aws-apitools-ec2cela peut être installé par

yum install -y aws-apitools-ec2 

Je joins son guide pour plus de référence.

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

Mansur Ali
la source
sur ubuntu 16.04 je n'ai pas pu trouver le paquet.
borracciaBlu
0

J'ai eu le même problème, mais après avoir supprimé la redirection stderr de mon entrée cron ( 2>@1), j'ai vu aws: command not founddans le journal.

En effet, l'AWS cli a été installé dans le dossier de base de l'utilisateur et j'avais ajouté une ligne à mon utilisateur .bash_profilepour ajouter le chemin AWS cli au $PATH. Curieusement, c'est en fait la façon dont la documentation d'installation d'AWS cli vous dit de l'installer. Mais l'utilisateur.bash_profile n'est pas utilisé lorsque la crontab de l'utilisateur est exécutée (du moins pas dans mon environnement de toute façon).

Donc, tout ce que j'ai fait pour résoudre ce problème était de m'assurer que mon script crontab avait également le aws cli sur son chemin. Donc, sous le shebang de mon script, je l'ai maintenant PATH=~/.local/bin:$PATH.

alexkb
la source
0

Pour moi, cela a fait l'affaire:

#!/bin/bash

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

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

L'utilisateur par défaut dans les instances EC2 d'aujourd'hui est ubuntu, et le dossier racine est le dossier de départ de l'utilisateur. C'est là que le aws cli existe également.

GotBatteries
la source
0

Pas le meilleur, mais j'ai dû fournir la configuration directement dans mon script shell / bash avant les commandes du client AWS. comme:

#!/bin/bash

export AWS_ACCESS_KEY_ID=<ZZZ>
export AWS_SECRET_ACCESS_KEY=<AAA>
export AWS_DEFAULT_REGION=<BBB>
aws s3 cp ....
user1859675
la source