めちゃくちゃ前にruby2でリリースしたアプリがあって、それをElasticbeanstalk(以下EB)でデプロイ・運用してたんですが
だいぶ前からAWSより「Ruby2.xのイメージはサポート終了してるから早く更新しろ」と
怒られていて、重い腰を上げて更新しました。(Ruby3.2のイメージに変更しました)
その時の手順も可能な限り残してブログにしようとは考えていたんですが
結局RailsやPumaのバージョンいくつにするか~とかで一つずつエラーつぶしていくしかないので頑張りましょう。
今回はアプリのデプロイ、起動には成功したんですが、利用しているイメージの仕様が変わったのか、rakeタスクがそのままでは動かなくなっていたのでその対応をメモしておきます。
そもそもrakeが動かなくなっていた理由
環境プロパティがアプリ実行時に動的に設定されていて、インスタンスに常に設定されているものではなくなっていたから。でした。
Ruby2のイメージを使っていた時は環境プロパティに設定したものは env
コマンドで確認することができましたが、(いつからそうなったのかはわかりませんが)Ruby3のイメージではenv
コマンドで確認することができませんでした。
なのでそのままシェルから rake db:migrate
とかを実行しようとすると、RAILS_ENV
が設定されていないというエラーが出てしまいました。
でもrakeしたいよね
自分の場合は、rakeタスクにテスト環境用の様々なデータ操作を行う処理だったり、crontabで実行したいバッチ処理などがあったのでrakeタスクを動かせるように修正する必要がありました。
rakeを動かしたいユーザでbundle installする
表題の通り。
$ cd /var/app/current
$ ./bin/bundle install
ただし/var/app/current/.bundle
はroot権限が必要なので、書き換えが必要である場合はroodログインして修正してください。
(ここも環境プロパティにBUNDLE_WITHOUT
が設定されていても、.bundle/config
には書き込まれていません。)
# 例:
$ sudo su -
$ cd /var/app/current
$ ./bin/bundle config set --local without 'test development'
EBに設定した環境プロパティをインスタンス内で取得する
EBのインスタンスに配置されているget-config
コマンドを利用すると取得できます。
# 環境プロパティ全体をjsonで取得する
/opt/elasticbeanstalk/bin/get-config environment
# 特定のキーの環境プロパティを取得する
/opt/elasticbeanstalk/bin/get-config environment -k RACK_ENV
XXXXXXXXXXXXXXX
上記を使ってrakeタスクを実行する
下記のスクリプトを ./rake_task.sh "db:migrate"
みたいに実行したらいけます。
# rake_task.sh
set -xe
DB_HOST=$(/opt/elasticbeanstalk/bin/get-config environment -k DB_HOST)
DB_PASS=$(/opt/elasticbeanstalk/bin/get-config environment -k DB_PASS)
RACK_ENV=$(/opt/elasticbeanstalk/bin/get-config environment -k RACK_ENV)
RAILS_MASTER_KEY=$(/opt/elasticbeanstalk/bin/get-config environment -k RAILS_MASTER_KEY)
export DB_HOST
export DB_PASS
export RACK_ENV
export RAILS_MASTER_KEY
cd /var/app/current
COMMAND="./bin/bundle exec rake $1"
eval $COMMAND
unset DB_HOST
unset DB_PASS
unset RACK_ENV
unset RAILS_MASTER_KEY
参考リンク
AWS公式 環境プロパティとその他のソフトウェアの設定
AWS公式 Elastic Beanstalk Ruby プラットフォームを使用する
AWS公式 プラットフォームスクリプトツール
Github elastic-beanstalk-samples
おまけ
ElasticBeanstalkと直接関係はありませんが、CodePipeline経由でデプロイした場合にエラーが出て失敗していたのでメモ。
下記の権限をIAMロールに追加することで解消しました。
{
"Action": [
"logs:DescribeLogGroups",
"logs:PutRetentionPolicy"
],
"Effect": "Allow",
"Resource": "*"
},