Nie można uruchomić AWS CLI z CRON (poświadczenia)

27

Próbuję uruchomić prosty skrypt kopii zapasowej AWS CLI. Pętla przechodzi przez linie w pliku dołączania, kopiuje te ścieżki do S3 i zrzuca dane wyjściowe do pliku dziennika. Kiedy uruchamiam to polecenie bezpośrednio, działa ono bez żadnego błędu. Kiedy uruchamiam go przez CRON, w moim dzienniku wyjściowym pojawia się błąd „Nie można zlokalizować danych logowania”.

Skrypt powłoki:

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

Dodałem wiersz do pliku konfiguracyjnego dopiero po tym, jak zobaczyłem błąd, myśląc, że to może go naprawić (chociaż jestem pewien, że tam domyślnie wygląda AWS).

Skrypt powłoki działa jako root. Widzę plik konfiguracyjny AWS w określonej lokalizacji. I wszystko wygląda dla mnie dobrze (jak powiedziałem, działa dobrze poza CRON).

binarno-organiczny
źródło
2
Wypróbuj bezwzględną ścieżkę do ~/.aws/config.
ceejayoz
Zdecydowanie wypróbowałem to pierwsze (używał /root/.aws/config), ale wróciłem do ~ / po zobaczeniu go w innych wątkach. Ten sam błąd w obu przypadkach.
binaryorganic
2
Nie bezpośrednia odpowiedź, ale komentarz na temat korzystania z kluczy API: Lepszą praktyką (i znacznie łatwiejszą) jest przypisywanie ról do instancji i tworzenie zasad wokół tych ról, a wtedy nie musisz wcale określać kluczy, lub niech leżą w postaci zwykłego tekstu na instancji. Niestety można to określić tylko podczas tworzenia instancji. Nawiasem mówiąc, do kopiowania plików dziennika (i kopii zapasowych itp.) Spójrz na narzędzia s3cmd, które zapewniają funkcjonalność podobną do rsync.
nico

Odpowiedzi:

20

Jeśli działa, gdy uruchamiasz go bezpośrednio, ale nie z crona, prawdopodobnie w środowisku jest coś innego. Możesz w ten sposób interaktywnie ratować swoje środowisko

set | sort > env.interactive

I zrób to samo w swoim skrypcie

set | sort > /tmp/env.cron

A potem diff /tmp/env.cron env.interactivei zobacz, co się liczy. Takie rzeczy PATHsą najbardziej prawdopodobnymi winowajcami.

pisklęta
źródło
4
Dzięki! Krok w kierunku samodzielnego rozwiązania problemu jest w zasadzie nieoceniony. Zdecydowanie było kilka różnic w zmiennej PATH, i myślę, że w tym przypadku to różnica w HOME była tym, co rzucało. Jeśli chodzi o mój konkretny problem, skończyło się na tym, że uruchomiłem to z pliku cron użytkownika, zamiast / etc / crontab, co rozwiązało wszystko po mojej stronie. Dzięki jeszcze raz!
binaryorganic
Dobrze. dodanie poprawnej PATHzmiennej ( echo $PATHpowie, jaka powinna być) w skrypcie zwykle ją rozwiązuje.
Fr0zenFyr
33

Gdy uruchamiasz zadanie z crontab, twoją $HOMEzmienną środowiskową jest/

Klient Amazon szuka jednego z nich

~/.aws/config

lub

~/.aws/credentials

Jeśli $HOME= /, to klient nie znajdzie tych plików

Aby działało, zaktualizuj skrypt, aby wyeksportował rzeczywisty katalog domowy $HOME

export HOME=/root

a następnie włóż pliki konfiguracyjne lub poświadczenia

/root/.aws/
Garreth McDaid
źródło
Pomogło to, wraz z następującą poprawką z stackoverflow.com/a/26480929/354709, która polegała na dodaniu bezwzględnej ścieżki do polecenia aws - ponieważ $ PATH nie był poprawnie ustawiony dla użytkownika root.
Dan Smart
2
To powinna być zaakceptowana odpowiedź.
Madbreaks,
6

Udało mi się rozwiązać ten problem poprzez poniżej :

export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_ACCESS_KEY_ID=XXXX
export AWS_SECRET_ACCESS_KEY=YYYY
Daniel Tronolone
źródło
1
Ale chodzi o aws configureto, abyś nie musiał wpisywać poświadczeń np. W skryptach. Zobacz odpowiedź wysłaną przez @chicks, aby rozwiązać ten problem poprawnie.
Madbreaks,
1
Nie przechowuj AWS_ACCESS_KEY_IDi AWS_SECRET_ACCESS_KEYwartości w skryptach. Pierwszy wiersz powinien już podać te wartości.
AWippler
2

Umieść ten kod przed wierszem polecenia, aby go wykonać w crontab -e

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Roberto Carlos Reyes Fernández
źródło
Wypróbowałem pierwsze rozwiązanie z różnicą, ale nic. sztuką była dla mnie zmienna PATH.
borracciaBlu
1

Pliki binarne narzędzia aws cli są zainstalowane pod /usr/local/bin/aws.

Wystąpił błąd polegający na tym, że użytkownik cron nie mógł uzyskać dostępu /usr/local/bin/awspodczas działania; ma dostęp tylko/usr/bin/

To, co zrobiłem, to utworzenie linku /usr/bindo aws za pomocą poniższego polecenia.

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

Dodałem także kilka zmian w moim skrypcie; oto przykładowa funkcja:

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

}

I wpis crona:

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

Ta metoda działała dla mnie.

Mansur Ali
źródło
Mansur, twoje formatowanie odpowiedzi jest całkowicie zepsute.
Aldekein
stosowanie pełnej ścieżki /usr/bin/awsjest kluczem do rozwiązania.
Ramratan Gupta
1

Ta linia w domyślnym .bashrcpliku dla użytkownika zapobiegnie uzyskaniu pełnego środowiska użytkownika przez powłoki nieinteraktywne (w tym zmienną PATH):

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

Skomentuj wyjście liniowe, aby umożliwić $HOME/.bashrcwykonanie z nieinteraktywnego kontekstu.

Musiałem także dodać jawne sourcepolecenie do skryptu powłoki, aby poprawnie skonfigurować środowisko:

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

Zobacz tę odpowiedź, aby uzyskać dodatkowe informacje.

Peter Gluck
źródło
1

Wszyscy wiemy, że zmienna środowiskowa $ PATH ma lokalizację plików binarnych. $ PATH of Crontab może nie mieć awscli lokalizacji.

Co możesz zrobić, to znaleźć ścieżkę do bsc awscli.

# which aws
/usr/local/bin/aws

i dodaj ścieżkę w $ PATH crontab, dodając poniżej linii na początku skryptu (po shebang).

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

To działało dla mnie !!!

Nijil
źródło
Twoja odpowiedź zadziałała dla mnie. Drapiąc się po głowie przez godzinę. Dzięki, kolego
Hussain7,
0

Wiem, że to nie jest idealne rozwiązanie, ale to działało dla mnie:

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
źródło
0

Aby dodać wartość dodaną, miałem problem z nową wersją bash podczas korzystania z awsclinarzędzia zainstalowanego za pomocą PIP i stwierdziłem, że nic nie będzie działać z tym narzędziem z nowymi wersjami bash.

Mogłem rozwiązać, instalując aws-apitools-ec2to można zainstalować przez

yum install -y aws-apitools-ec2 

Załączam jego przewodnik, aby uzyskać więcej informacji.

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

Mansur Ali
źródło
na Ubuntu 16.04 nie mogłem znaleźć pakietu.
borracciaBlu
0

Miałem ten sam problem, ale po usunięciu przekierowania stderr z mojego wpisu cron ( 2>@1) zobaczyłem aws: command not foundw dzienniku.

Wynika to z faktu, że cli AWS zostało zainstalowane w folderze domowym użytkownika, a ja dodałem linię do mojego użytkownika, .bash_profileaby dodać ścieżkę cli AWS do pliku $PATH. Co dziwne, w rzeczywistości jest to sposób, w jaki dokumentacja instalacji AWS cli każe ci ją zainstalować. Ale użytkownik .bash_profilenie przyzwyczaja się, gdy crontab użytkownika jest wykonywany (przynajmniej nie w moim środowisku).

Więc wszystko, co zrobiłem, aby to naprawić, to upewnić się, że mój skrypt crontab ma również aws cli na swojej drodze. Tak więc poniżej zera mojego skryptu mam teraz PATH=~/.local/bin:$PATH.

alexkb
źródło
0

Dla mnie to załatwiło sprawę:

#!/bin/bash

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

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

Domyślnym użytkownikiem w dzisiejszych instancjach EC2 jest ubuntu, a folderem głównym jest folder domowy użytkowników. Tam właśnie istnieje również aws cli.

GotBatteries
źródło
0

Nie najlepsze, ale musiałem dostarczyć konfigurację bezpośrednio w moim skrypcie powłoki / bash przed poleceniami klienta AWS. lubić:

#!/bin/bash

export AWS_ACCESS_KEY_ID=<ZZZ>
export AWS_SECRET_ACCESS_KEY=<AAA>
export AWS_DEFAULT_REGION=<BBB>
aws s3 cp ....
użytkownik1859675
źródło