AWS CLI kann nicht über CRON ausgeführt werden (Anmeldeinformationen)

27

Versuch, ein einfaches AWS CLI-Sicherungsskript auszuführen. Es durchläuft Zeilen in einer Include-Datei, sichert diese Pfade bis S3 und gibt die Ausgabe in eine Protokolldatei aus. Wenn ich diesen Befehl direkt ausführe, läuft er fehlerfrei. Wenn ich es über CRON ausführe, wird in meinem Ausgabeprotokoll der Fehler "Anmeldeinformationen können nicht gefunden werden" angezeigt.

Das Shell-Skript:

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

Ich habe die Zeile erst zur Konfigurationsdatei hinzugefügt, nachdem der Fehler aufgetreten ist, weil ich dachte, dies könnte ihn beheben (obwohl ich mir ziemlich sicher bin, dass AWS dort standardmäßig angezeigt wird).

Shell-Skript wird als root ausgeführt. Ich kann die AWS-Konfigurationsdatei am angegebenen Speicherort sehen. Und alles sieht gut für mich aus (wie ich schon sagte, es läuft gut außerhalb von CRON).

binärorganisch
quelle
2
Versuchen Sie einen absoluten Pfad zu ~/.aws/config.
Ceejayoz
Das habe ich definitiv zuerst versucht (habe /root/.aws/config verwendet), bin aber zurück zu ~ / gesprungen, nachdem ich es in einigen anderen Threads gesehen habe. Gleicher Fehler wie auch immer.
Binaryorganic
2
Keine direkte Antwort, sondern ein Kommentar zur Verwendung der API-Schlüssel: Es wird empfohlen (und ist viel einfacher), Ihren Instanzen Rollen zuzuweisen und Richtlinien für diese Rollen zu erstellen. In diesem Fall müssen Sie die Schlüssel überhaupt nicht angeben Lassen Sie sie im Klartext auf der Instanz herumliegen. Leider kann dies nur zum Zeitpunkt der Instanzerstellung angegeben werden. Schauen Sie sich zum Kopieren von Protokolldateien (und Backups usw.) auch die s3cmd-Tools an, die ähnliche Funktionen wie rsync bieten.
Nico

Antworten:

20

Wenn es funktioniert, wenn Sie es direkt ausführen, aber nicht von cron, liegt wahrscheinlich etwas anderes in der Umgebung vor. Sie können Ihre Umgebung auf diese Weise interaktiv sichern

set | sort > env.interactive

Und machen Sie dasselbe in Ihrem Skript

set | sort > /tmp/env.cron

Und dann diff /tmp/env.cron env.interactiveund sehen, worauf es ankommt. Dinge wie PATHsind die wahrscheinlichsten Schuldigen.

Küken
quelle
4
Vielen Dank! Ein Schritt, um das Problem selbst zu beheben, ist von unschätzbarem Wert. Es gab definitiv mehrere Unterschiede in der PATH-Variablen, und ich denke, in diesem Fall war es der Unterschied in HOME, der die Dinge aus der Bahn warf. Was mein spezielles Problem angeht, habe ich es letztendlich nur aus der Cron-Datei des Benutzers heraus ausgeführt und nicht aus / etc / crontab, was alles in meinem Sinne gelöst hat. Danke noch einmal!
Binaryorganic
Recht. Das Hinzufügen einer korrekten PATHVariablen ( echo $PATHdie angibt , wie sie lauten soll) im Skript löst sie normalerweise .
Fr0zenFyr
33

Wenn Sie einen Job über crontab ausführen, $HOMElautet Ihre Umgebungsvariable/

Der Amazon-Client sucht nach

~/.aws/config

oder

~/.aws/credentials

Wenn $HOME= /, findet der Client diese Dateien nicht

Aktualisieren Sie Ihr Skript, damit es ein tatsächliches Basisverzeichnis für exportiert $HOME

export HOME=/root

und legen Sie dann eine Konfiguration oder Anmeldeinformationen-Dateien in

/root/.aws/
Garreth McDaid
quelle
Dies half zusammen mit dem folgenden Fix von stackoverflow.com/a/26480929/354709 , bei dem der absolute Pfad für den Befehl aws hinzugefügt wurde, da $ PATH im Root-Benutzer nicht richtig festgelegt war.
Dan Smart
2
Dies sollte die akzeptierte Antwort sein.
Madbreaks
6

Ich konnte dieses Problem folgendermaßen lösen :

export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_ACCESS_KEY_ID=XXXX
export AWS_SECRET_ACCESS_KEY=YYYY
Daniel Tronolone
quelle
1
Das Ganze aws configureist jedoch so, dass Sie keine Anmeldeinformationen in z. B. Skripts einfügen müssen. Lesen Sie die Antwort von @chicks, um das Problem zu lösen.
Madbreaks
1
Speichern Sie nicht AWS_ACCESS_KEY_IDund AWS_SECRET_ACCESS_KEYWerte in Skripten. Die erste Zeile sollte diese Werte bereits angegeben haben.
AWippler
2

Stellen Sie diesen Code vor die Befehlszeile, damit er in crontab -e ausgeführt wird

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Roberto Carlos Reyes Fernández
quelle
Ich habe die erste Lösung mit dem Diff ausprobiert, aber nichts. Der Trick für mich war die PATH-Variable.
BorracciaBlu
1

Die Binärdateien des aws cli-Tools werden unter installiert /usr/local/bin/aws.

Der Fehler, den ich hatte, ist, dass der Cron-Benutzer /usr/local/bin/awswährend der Ausführung nicht zugreifen konnte ; es kann nur zugreifen/usr/bin/

Ich habe /usr/binmit dem folgenden Befehl einen Link für aws erstellt.

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

Ich habe auch einige Änderungen in meinem Skript hinzugefügt. Hier ist eine Beispielfunktion:

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

}

Und der Cron-Eintrag:

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

Diese Methode hat bei mir funktioniert.

Mansur Ali
quelle
Mansur, deine Antwortformatierung ist komplett kaputt.
Aldekein
Der vollständige Pfad /usr/bin/awsist der Schlüssel zur Lösung.
Ramratan Gupta
1

Diese Zeile in der Standarddatei .bashrcfür den Benutzer verhindert, dass nicht interaktive Shells die vollständige Benutzerumgebung abrufen (einschließlich der Variablen PATH):

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

Kommentieren Sie den Zeilenausgang, damit er $HOME/.bashrcin einem nicht interaktiven Kontext ausgeführt werden kann.

Ich musste sourcemeinem Shell-Skript auch einen expliziten Befehl hinzufügen , um die Umgebung korrekt einzurichten:

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

Weitere Informationen finden Sie in dieser Antwort .

Peter Glück
quelle
1

Wir alle wissen, dass die Umgebungspfadvariable $ PATH die Position von Binärdateien hat. $ PATH von Crontab verfügt möglicherweise nicht über die Position awscli.

Was Sie tun können, ist, den Pfad von awscli binary zu finden.

# which aws
/usr/local/bin/aws

und füge den Pfad in $ PATH von crontab hinzu, indem du am Anfang deines Skripts (nach shebang) die folgende Zeile hinzufügst.

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

Das hat bei mir funktioniert !!!

Nijil
quelle
Ihre Antwort hat für mich funktioniert. Ich kratzte mich eine Stunde am Kopf. Vielen Dank, Kumpel
Hussain7
0

Ich weiß, dass es nicht die perfekte Lösung ist, aber das hat bei mir funktioniert:

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
quelle
0

Nur um einen Mehrwert zu schaffen, hatte ich ein Problem mit der neuen Bash-Version, während awscliich das über PIP installierte Tool verwendete. Bei neuen Bash-Versionen stellte ich fest, dass mit diesem Tool nichts mehr funktioniert.

Ich war in der Lage zu lösen, indem ich aws-apitools-ec2dieses anbringe, kann durch anbringen

yum install -y aws-apitools-ec2 

Ich füge den Leitfaden als Referenz bei.

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

Mansur Ali
quelle
Auf Ubuntu 16.04 konnte ich das Paket nicht finden.
BorracciaBlu
0

Ich hatte das gleiche Problem, aber nachdem ich die stderr-Umleitung von meinem cron-Eintrag ( 2>@1) entfernt hatte, sah ich es aws: command not foundim Protokoll.

Dies liegt daran, dass die AWS-CLI im Basisordner des Benutzers installiert wurde und ich meinem Benutzer eine Zeile hinzugefügt habe .bash_profile, um den AWS-CLI-Pfad zum hinzuzufügen $PATH. Seltsamerweise werden Sie in der AWS-CLI-Installationsdokumentation auf diese Weise aufgefordert, sie zu installieren. Der Benutzer wird .bash_profilejedoch nicht verwendet, wenn die crontab des Benutzers ausgeführt wird (jedenfalls nicht in meiner Umgebung).

Alles was ich getan habe, um dies zu beheben, war sicherzustellen, dass mein Crontab-Skript auch die AWS-CLI in seinem Pfad hatte. Also habe ich jetzt unter dem Knall meines Drehbuchs PATH=~/.local/bin:$PATH.

alexkb
quelle
0

Für mich war das der Trick:

#!/bin/bash

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

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

Der Standardbenutzer in heutigen EC2-Instanzen ist ubuntu, und der Stammordner ist der Stammordner dieses Benutzers. Dort existiert auch die aws cli.

GotBatteries
quelle
0

Nicht die beste, aber ich musste die Konfiguration direkt in meinem Shell- / Bash-Skript bereitstellen, bevor der AWS-Client Befehle ausführte. mögen:

#!/bin/bash

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