Não é possível executar a CLI da AWS a partir do CRON (credenciais)

27

Tentando executar um script de backup simples da AWS CLI. Ele percorre as linhas em um arquivo de inclusão, faz backup desses caminhos até o S3 e despeja a saída em um arquivo de log. Quando executo esse comando diretamente, ele é executado sem nenhum erro. Quando o executo pelo CRON, recebo o erro "Não é possível localizar credenciais" no meu log de saída.

O 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

Eu apenas adicionei a linha ao arquivo de configuração depois que comecei a ver o erro, pensando que isso pode corrigi-lo (mesmo tendo certeza de que é onde a AWS parece por padrão).

O script do shell está sendo executado como root. Eu posso ver o arquivo de configuração da AWS no local especificado. E tudo parece bom para mim (como eu disse, funciona bem fora do CRON).

binário-orgânico
fonte
2
Tente um caminho absoluto para ~/.aws/config.
ceejayoz
Definitivamente tentei isso primeiro (estava usando /root/.aws/config), mas voltou para ~ / depois de vê-lo em alguns outros threads. Mesmo erro de qualquer maneira.
binaryorganic
2
Não é uma resposta direta, mas um comentário sobre o uso das chaves da API: é uma prática melhor (e muito mais fácil) atribuir funções às suas instâncias, criar políticas em torno dessas funções e, portanto, não é necessário especificar as chaves, ou tê-los espalhados em texto simples na instância. Infelizmente, isso só pode ser especificado no momento da criação da instância. Além disso, para copiar arquivos de log (e backups etc), consulte as ferramentas s3cmd, que fornecem funcionalidade semelhante ao rsync.
Nico

Respostas:

20

Se funcionar quando você o executa diretamente, mas não a partir do cron, provavelmente há algo diferente no ambiente. Você pode salvar seu ambiente interativamente fazendo

set | sort > env.interactive

E faça a mesma coisa no seu script

set | sort > /tmp/env.cron

E então diff /tmp/env.cron env.interactivee veja o que importa. Coisas como PATHsão os culpados mais prováveis.

pintinhos
fonte
4
Obrigado! Um passo para ser capaz de solucionar o problema sozinho é basicamente inestimável. Definitivamente, havia várias diferenças na variável PATH, e eu acho que, nesse caso, era a diferença no HOME que estava jogando coisas fora. Quanto ao meu problema específico, acabei executando isso no arquivo cron do usuário, em vez de / etc / crontab, que resolveu tudo do meu lado. Obrigado novamente!
binaryorganic
Direita. adicionar uma PATHvariável correta ( echo $PATHdirá o que deveria ser) no script geralmente a resolve.
Fr0zenFyr
33

Quando você executa um trabalho no crontab, sua $HOMEvariável de ambiente é/

O cliente Amazon procura por

~/.aws/config

ou

~/.aws/credentials

Se $HOME= /, o cliente não encontrará esses arquivos

Para fazê-lo funcionar, atualize seu script para que exporte um diretório inicial real para $HOME

export HOME=/root

e, em seguida, coloque os arquivos de configuração ou credenciais em

/root/.aws/
Garreth McDaid
fonte
Isso ajudou, juntamente com a seguinte correção de stackoverflow.com/a/26480929/354709, que envolveu a adição do caminho absoluto para o comando aws - como $ PATH não foi definido corretamente no usuário root.
Dan Inteligente
2
Essa deve ser a resposta aceita.
precisa saber é o seguinte
6

Consegui resolver esse problema da seguinte maneira :

export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_ACCESS_KEY_ID=XXXX
export AWS_SECRET_ACCESS_KEY=YYYY
Daniel Tronolone
fonte
1
Mas o objetivo principal aws configureé fazer com que você não precise colocar credenciais, por exemplo, scripts. Veja a resposta postada por @chicks para resolver isso corretamente.
precisa saber é o seguinte
1
Não armazene AWS_ACCESS_KEY_IDe AWS_SECRET_ACCESS_KEYvalores em scripts. A primeira linha já deveria ter fornecido esses valores.
AWippler
2

Coloque esse código antes da linha de comando para ser executado no crontab -e

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Roberto Carlos Reyes Fernández
fonte
Eu tentei a primeira solução com o diff, mas nada. o truque para mim foi a variável PATH.
borracciaBlu
1

Os binários da ferramenta aws cli estão instalados em /usr/local/bin/aws.

O erro que tive foi que o usuário cron não pôde acessar /usr/local/bin/awsdurante a execução; só pode acessar/usr/bin/

O que fiz foi criar um link /usr/binpara aws com o comando abaixo.

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

Eu também adicionei algumas mudanças no meu script; aqui está uma função de exemplo:

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

}

E a entrada cron:

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

Este método funcionou para mim.

Mansur Ali
fonte
Mansur, sua formatação de respostas está completamente quebrada.
Aldekein 27/09/16
usar o caminho completo /usr/bin/awsé a chave para a solução.
Ramratan Gupta 12/03/19
1

Esta linha no .bashrcarquivo padrão para o usuário impedirá que shells não interativos obtenham o ambiente completo do usuário (incluindo a variável PATH):

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

Comente a linha para permitir $HOME/.bashrca execução a partir de um contexto não interativo.

Eu também precisei adicionar um sourcecomando explícito ao meu script de shell para configurar o ambiente corretamente:

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

Veja esta resposta para informações adicionais.

Peter Gluck
fonte
1

Todos sabemos que a variável de caminho do ambiente $ PATH possui a localização dos binários. $ PATH do Crontab pode não ter a localização awscli.

O que você pode fazer é encontrar o caminho do binário awscli.

# which aws
/usr/local/bin/aws

e adicione o caminho em $ PATH do crontab adicionando a linha abaixo no início do seu script (após shebang).

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

Isso funcionou para mim !!!

Nijil
fonte
Sua resposta funcionou para mim. Coçando a cabeça por uma hora. Obrigado, amigo
Hussain7 25/06
0

Eu sei que não é a solução perfeita, mas que funcionou para mim:

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

Apenas para adicionar algum valor agregado, eu estava tendo problemas com a nova versão do bash ao usar a awscliferramenta instalada via PIP, e descobri que nada funcionaria com essa ferramenta nas novas versões do bash.

Eu era capaz de resolver instalando aws-apitools-ec2este pode ser instalado por

yum install -y aws-apitools-ec2 

Estou anexando seu guia para mais referências.

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

Mansur Ali
fonte
no ubuntu 16.04 não consegui encontrar o pacote.
borracciaBlu
0

Eu tive o mesmo problema, mas depois de remover o redirecionamento stderr da minha entrada cron ( 2>@1), vi aws: command not foundno log.

Isso ocorre porque o cli da AWS foi instalado na pasta inicial do usuário e eu adicionei uma linha ao meu usuário .bash_profilepara adicionar o caminho do cli da AWS ao $PATH. Estranhamente, é assim que a documentação de instalação do AWS cli diz para você instalá-lo. Mas o usuário .bash_profilenão se acostuma quando o crontab do usuário é executado (pelo menos não no meu ambiente).

Então, tudo o que fiz para corrigir isso foi garantir que meu script crontab também tivesse o aws cli em seu caminho. Então, abaixo do shebang do meu script, eu tenho agora PATH=~/.local/bin:$PATH.

alexkb
fonte
0

Para mim, isso fez o truque:

#!/bin/bash

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

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

O usuário padrão nas instâncias atuais do EC2 é o ubuntu e a pasta raiz é a pasta inicial do usuário. É aí que o aws cli existe também.

GotBatteries
fonte
0

Não é o melhor, mas tive que fornecer a configuração diretamente no meu script shell / bash antes dos comandos do cliente da AWS. gostar:

#!/bin/bash

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