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 comparison. This 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).
- 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
- 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
- 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.
- 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.
- 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
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
- 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.ymluses 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
pggems 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
sgto 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.
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.
- 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:firstname.lastname@example.org: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.
- 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
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
eb sshto connect to an EC2 instance in your environment.
- That’s all!
- Installing the CLI for Elastic Beanstalk
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.
To explore more interesting information subscribe to our weekly newsletter!