1
votes

I am getting following Error while creating Elastic Beanstalk Environment

Command failed on instance. Return code: 1 Output: (TRUNCATED)... ^ /var/app/ondeck/config/environment.rb:5:in <top (required)>' /opt/rubies/ruby-2.4.3/bin/bundle:23:inload' /opt/rubies/ruby-2.4.3/bin/bundle:23:in `' Tasks: TOP => db:migrate => environment (See full trace by running task with --trace). Hook /opt/elasticbeanstalk/hooks/appdeploy/pre/12_db_migration.sh failed. For more detail, check /var/log/eb-activity.log using console or EB CLI.

In /var/log/eb-activity.log file, I found following Errors -

Tasks: TOP => db:migrate => environment (See full trace by running task with --trace) (Executor::NonZeroExitStatus)

AppDeployStage0/AppDeployPreHook/12_db_migration.sh] : Activity failed.

AppDeployStage0/AppDeployPreHook] : Activity failed.

AppDeployStage0] : Activity failed.

Application update - CommandCMD-AppDeploy failed

1
Please post more/all of your /var/log/eb-activity.log file so that we can help figure out why your migration failed.Brian
I'm curious to know if rake db:migrate works correctly locally.progfan

1 Answers

3
votes

I encountered this same problem when using Elastic Beanstalk with an external Amazon RDS database. Basically, the problem is that the Elastic Beanstalk pre-deployment scripts will attempt to migrate the database before it even exists.

There are two ways I discovered for how to solve this.

The first way is to set the RAILS_SKIP_MIGRATIONS=true environment variable on your app configuration. This should allow you to at least get the codebase deployed. After that, you can use eb ssh to shell into the app, browse to the /var/app/current/ folder, and manually run bundle exec rails db:create and bundle exec rails db:migrate.

Another way to solve the problem is to create an app pre-deploy shell script hook file in the /opt/elasticbeanstalk/hooks/appdeploy/pre/ folder.

I used the /opt/elasticbeanstalk/hooks/appdeploy/pre/12_db_migration.sh file as reference, and here's what I came up with.

Create a file in your project called /.ebextensions/0001_rails_db_create.config, with the following contents:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/11_create_db.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      set -xe

      EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
      EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
      EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)

      . $EB_SUPPORT_DIR/envvars

      RAKE_TASK="db:create"

      . $EB_SCRIPT_DIR/use-app-ruby.sh

      cd $EB_APP_STAGING_DIR

      if su -s /bin/bash -c "bundle exec $EB_SCRIPT_DIR/check-for-rake-task.rb $RAKE_TASK" $EB_APP_USER; then
          if [ "$RAILS_SKIP_DB_CREATE" = "true" ]; then
              echo "Skipping database creation (RAILS_SKIP_DB_CREATE=true)."
          else
              su -s /bin/bash -c "leader_only bundle exec rake db:create" $EB_APP_USER
          fi
      else
          echo "No $RAKE_TASK task in Rakefile, skipping database creation."
      fi

Commit that file to your git repo and then run eb deploy.

This should create the shell script hook file which will create the rails db if it doesn't exist. The database migration shell script hook file should run immediately afterwards, since its name starts with the number 12.

Once this script is in place, if you ever want to bypass it, you can set the RAILS_SKIP_DB_CREATE=true environment variable on your app.