How to deploy a Rails app on AWS Elastic Beanstalk

How to deploy a Rails app on AWS Elastic Beanstalk
Average rating: 0
(0 votes)

Last time we showed you how to deploy Elixir on Elastic Beanstalk. But as an agency with Rails among favorite frameworks, Syndicode would like to share with you the tutorial on how to deploy a Rails app on AWS Elastic Beanstalk. By the way, we’re looking for the Rails developer

A little reminder that Elastic Beanstalk is a cloud deployment service that automates the process of setting applications up on the AWS (Amazon Web Services). Before you proceed to the tutorial, you can explore AWS vs Heroku comparisonThis will make you understand why we choose AWS.

This tutorial will show you how to deploy a Rails app on AWS Elastic Beanstalk with the command-line interface (CLI).

  1. Installing the CLI for Elastic Beanstalk
    On Mac, install aws-elasticbeanstalk using HomeBrew.

    brew install aws-elasticbeanstalk
    

    If you’re not using HomeBrew or if you’re on Linux, you can install it using pip.

    sudo pip install awsebcli
    

    On Windows, run

    pip install awsebcli
  2. Clone the Rails app
    We’ll use Git to clone the sample app from Basic Rails GTD app. If you want to use your own Rails application, the Elastic Beanstalk CLI requires that you put the app in a Git repository. 

    git clone https://github.com/engineyard/todo.git
  3. Create IAM Roles
    To create 2 IAM roles we’ll follow the instructions from the AWS site. We need aws-elasticbeanstalk-ec2-roleandaws-elasticbeanstalk-service-role. While we are using the Elastic Beanstalk CLI to create the application and environment, we’ll click “create new application” on the Elastic Beanstalk console for the sole purpose of creating these IAM roles. We need to do this only once. Do it one by one: 

    • Open the Elastic Beanstalk console.
    • Choose to Create New Application.
    • Proceed through the wizard until you reach the Permissions page.
    • Choose Next to open the IAM console.
    • Choose Allow to create the roles.
  4. Setup Elastic Beanstalk CLI
    cd todo
    eb init
    

    You need an AWS Access Key and an AWS Secret Access Key. If you don’t have these, go to the IAM console to create a user and download the credentials. You can select the defaults for the region, application to use (Create new Application), and the platform version. In the todo app we shared, a platform version is already included. If you’re using your own Rails app, make sure you add Ruby 2.3 Puma.

  5. Create the environment
    eb create todo_production
    

    Elastic Beanstalk will create a Security Group, ELB, and Auto Scaling group for you. In 3 minutes your environment will be ready, so you can check the app with

    eb open
    

    Environment Info:

    Sample deployment application by Engine Yard

    Pay attention to:

    • Ruby is in /opt/rubies/ruby-2.3.4
    • The Rails app is in /var/app/current
    • The user is named web app
  6. Create a database
    The setup in todo application is a bit wrong for using in a real app. Todo app works even if we don’t set up a database because config/database.yml uses a sqlite3 database. The todo_production environment only has one EC2 instance so it’s fine for now. But if the Auto Scaling group creates a second EC2 instance, this new instance will have its own sqlite3 database which is not what you want.To use a central database, delete config/database.yml. We don’t need this file as we’ll be using DATABASE_URL. 

    git rm config/database.yml
    git commit -m 'Remove database.yml'
    

    Create an RDS instance using the RDS console. You can use either MySQL or PostgreSQL. Both are supported by the todo application as the mysql2 and pg gems are already part of the Gemfile. Enter “todo” on the optional field database name. The logical database will be created after the RDS instance is created. Set Publicly Accessible to No for security purposes. Once the RDS instance is ready, click the Details icon and click the Security Group. You’ll see something like rds-launch-wizard-2 (sg-041b107e).

    On the Security Group page, click Inbound then Edit. Add a rule for PostgreSQL. Select Custom as the source and enter the Security Group of the Elastic Beanstalk environment. Type sg to bring up the list of Security Groups.

    If you can’t find the correct Security Group, it has the Elastic Beanstalk environment id on the group name. To get your environment id, type eb status. For example, my environment id is e-kq7hjkf7dt and my Security Group name is awseb-e-kq7hjkf7dt-stack-AWSEBSecurityGroup-44MI138FQVG. Do not select the one with AWSEBLoadBalancerSecurityGroup on the name.

    Captured by Engine Yard

    The EC2 instances created by Elastic Beanstalk should now have access to the RDS instance. You can also create an RDS instance tied up to the Elastic Beanstalk environment. However, this is not recommended because when you terminate the environment, the RDS instance will be terminated too.

  7. Set database_url
    Set the DATABASE_URL environment variable using the RDS credentials. The format is db_type://username:password@hostname:port/db_name.For example, if we created a PostgreSQL instance, with the following credentials: 

    user: engineyard
    password: mysecretpassword
    hostname: eypostgres.cjb9zibjzcpd.us-west-2.rds.amazonaws.com
    port: 5432
    db name: todo
    

    Then we should run:

    eb setenv DATABASE_URL=postgres://engineyard:mysecretpassword@eypostgres.cjb9zibjzcpd.us-west-2.rds.amazonaws.com:5432/todo

    Next, deploy the app without database.yml and open the page

    eb deploy
    eb open
    

    You now have a Rails app running on Elastic Beanstalk that uses a standalone RDS instance.

  8. Secret Key Base
    Set SECRET_KEY_BASE if you’re using this environment variable. Or if you’re using encrypted Rails secrets, set RAILS_MASTER_KEY.Generate a new secret key base with bundle exec rake secret

    eb setenv SECRET_KEY_BASE=
    cccae61c0c117c787745b596655caa50062dc3fc739505df02e209d9e737a2f39ab484d20e63d5937e1c58901e81109523807f66be421728851fecc2262ed5a8
  9. SSH
    When you run eb init, you can tell it to add your public key. It can also create a new keypair. If you have already run eb init, you can run it again with the --interactive option. Run eb ssh to connect to an EC2 instance in your environment.
  10. That’s all!

That was an easy way to deploy Rails applications on AWS Elastic Beanstalk. You give up some control as the supported Ruby versions and App servers are limited. Support for background workers like Sidekiq needs improvement. Currently, you have to create a file on .ebextensions and the Sidekiq workers run on the same instance as the Rails application. On a medium-sized application, you should have a dedicated instance for Sidekiq.

Useful links

  1. HomeBrew
  2. Basic Rails GTD app
  3. AWS site
  4. Elastic Beanstalk console
  5. IAM console
  6. Encrypted Rails secrets

To explore more interesting information subscribe to our weekly newsletter!

Rate this article, if you like it

Thanks! You’ve rated this material!

Got a project? Let's discuss it!

*By submitting this form you agree with our Privacy Policy.

Mailing & Legal Address

Syndicode Inc. 340 S Lemon Ave #3299, Walnut CA, 91789, USA

Visiting & Headquarters address
Kyiv Sofiivska 1/2a, 01001, Kyiv, Ukraine
Dnipro Hlinky 2, of. 1003, 49000, Dnipro, Ukraine
Email info@syndicode.com
Phone (+1) 9035021111