2017-01-12 27 views
1

AWS Elasticbeanstalk(EB)でdjango manage.pyタスクをcron経由で実行しようとしています。ファイルへのAWS環境変数の保存方法 - & '

*/10 * * * * root /usr/local/bin/notification_cron.sh > /dev/null 

notification_cron.shスクリプトはジャンゴmanage.pyタスクを呼び出します。

Djangoには、EBの環境変数(RDS_PORT、RDS_DB_NAME、RDS_PASSWORDなど)が必要です。ですから、これらの環境変数をデプロイ時にファイルに保存し、それらをmanage.pyタスクを呼び出すbashスクリプトに再ロードします。

これは.ebextensionsで私の展開の設定の一部です:

commands: 
    001_envvars_to_bash_source_file: 
    command: | 
     # source our elastic beanstalk environment variables 
     /opt/elasticbeanstalk/bin/get-config --output YAML environment|perl -ne "/^\w/ or next; s/: /=/; print qq|\$_|" > /usr/local/bin/envvars 
     chmod 755 /usr/local/bin/envvars 

files: 
    "/usr/local/bin/notification_cron.sh": 
    mode: "000755" 
    owner: root 
    group: root 
    content: | 
     #!/usr/bin/env bash 

     AWS_CONFIG_FILE="/home/ec2-user/.aws/config" 
     set -o allexport 
     # Loading environment data 
     source /usr/local/bin/envvars 
     set +o allexport 
     cd /opt/python/current/app/ 
     source /opt/python/run/venv/bin/activate 
     python manage.py my_management_task 

問題が

/opt/elasticbeanstalk/bin/get-config --output YAML environment|perl -ne "/^\w/ or next; s/: /=/; print qq|\$_|" > /usr/local/bin/envvars 

または代替同等

/opt/elasticbeanstalk/bin/get-config environment --output yaml | sed -n '1!p' | sed -e 's/^\(.*\): /\1=/g' > /usr/local/bin/envvars 

内容のをsedの行によって引き起こされます/usr/local/bin/envvarsは常に引用符で囲まれているわけではありません:

PYTHONPATH="/opt/python/current/app/mydjangoapp:$PYTHONPATH" 
DJANGO_SETTINGS_MODULE=mydjangoapp.settings 
AWS_ACTIVE='true' 
RDS_PORT='5432' 
RDS_HOSTNAME=hostname.host.us-east-1.rds.amazonaws.com 
RDS_USERNAME=master 
RDS_DB_NAME=ebdb 
RDS_PASSWORD=My&Password 

これは、環境変数が "&"という文字を持つ場合に問題を引き起こします。

'RDS_PASSWORD': My&Password 

I source /usr/local/bin/envvarsは、Djangoのmanage.pyを呼び出す前に戻って私のスクリプトにインポートするとき、bashは「&」の文字でこれを分割します。

Phew。私の質問は:

どのように私はRDS_PORT='5432'のような他の線を壊すことなく(必要な二重引用符に注意してください)/usr/local/bin/envvarsファイルにRDS_PASSWORD="My&Password"を得るのですか?あなたは以下のような何かを行うことができますGNU sedを使用

+0

のですか? – Inian

+0

envvarsファイルは、AWSのget-config(YAMLの環境変数をダンプする)を使用して配備中に自動的に作成され、with =と置き換えてファイルに配管します。それはPYTHONPATHを二重引用符で囲み、一重引用符RDS_PORTを引用し、RDS_PASSWORDを引用符で囲まない。すでに引用符で囲まれた変数を二重引用符で囲まずに、すべてを引用符で囲むか、RDS_PASSWORDだけを二重引用符で囲みますか? – Pranab

+0

私がこれを尋ねた理由は、これに対してどのように解決策が期待されますか?別のスクリプトを手動で実行するか、他のスクリプトと組み合わせるか? – Inian

答えて

2

sed -r 's/RDS_PASSWORD=([[:graph:]]+)/RDS_PASSWORD="\1"/' /usr/local/bin/envvars 
PYTHONPATH="/opt/python/current/app/mydjangoapp:$PYTHONPATH" 
DJANGO_SETTINGS_MODULE=mydjangoapp.settings 
AWS_ACTIVE='true' 
RDS_PORT='5432' 
RDS_HOSTNAME=hostname.host.us-east-1.rds.amazonaws.com 
RDS_USERNAME=master 
RDS_DB_NAME=ebdb 
RDS_PASSWORD="My&Password" 

はその後、インプレース置換をsed-iフラグを追加することができます。私は[:punct:]の一部として

‘[:graph:]’ 
Graphical characters: ‘[:alnum:]’ and ‘[:punct:]’. 

特殊文字である文字クラス[[:graph:]]を使用していたこれらの上記のいずれかの文字がRDS_PASSWORD変数を構成するのであればsedは置換を扱うことができる

! " # $ % & ' () * + , - ./: ; <=> ? @ [ \ ]^_ ` { | } ~ 

です。

使用できる構文、ファイルになぜだけではなく、二重引用符すべての変数

/opt/elasticbeanstalk/bin/get-config environment --output yaml | \ 
    sed -n '1!p' | sed -e 's/^\(.*\): /\1=/g' | \ 
    sed -r 's/RDS_PASSWORD=([[:graph:]]+)/RDS_PASSWORD="\1"/' > /usr/local/bin/envvars 
+0

/opt/elasticbeanstalk/bin/get-configの出力をパイプする方法はありますか?--output yaml | sed -n '1!p' | sed -r 's/RDS_PASSWORD =([[:グラフ:]] +)/ RDS_PASSWORD = "\ 1" /'>/usr/local/bin/envvars – Pranab

+0

@Pranab:アップデートで問題が解決しましたか? – Inian

+0

展開にはしばらく時間がかかりました。それは完璧に、おかげで動作します。 – Pranab

関連する問題