Setup EB + Ruby on Rails

Updated at 2015-10-06 04:22

This is a simple guide how to create a Ruby on Rails application in Elastic Beanstalk, behind load balancer and optional auto-scaling.

You need aws cli, eb cli and Ruby, I use rbenv to manage my Ruby versions. Use versions from Supported Platforms List

pip install awscli awsebcli
rbenv install 2.2.2
rbenv global 2.2.2

# list available elastic beanstalk platform in a region
eb platform list -r us-west-2
# we are going to use the ruby-2.2-(puma)

Write the Application

# example project name is `joru`
rails new joru
cd joru
# Gemfile, add the following
gem 'puma', '2.10.2'
brew install openssl
bundle config build.puma --with-opt-dir='/usr/local/Cellar/openssl/1.0.2d_1/'
bundle install
rails g controller RootPages index
# edit config/routes
Rails.application.routes.draw do
  root "root_pages#index"
rails server
# http://localhost:3000
# works? ok close it

Defining the Elastic Beanstalk application

Create new key pair. EC2 > Key Pairs > Create Key Pair. Name it eb-joru. Move it to ~/.ssh and execute chmod 0600 eb-joru.pem on it.

Create service-role-trust.json.

    "Version": "2012-10-17",
    "Statement": [
        "Sid": "1",
        "Effect": "Allow",
        "Principal": {
          "Service": ""
        "Action": "sts:AssumeRole",
        "Condition": {
          "StringEquals": {
            "sts:ExternalId": "elasticbeanstalk"

Create instance-profile-trust.json.

    "Version" : "2012-10-17",
    "Statement": [
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "Service": ""
            "Action": "sts:AssumeRole"

Create a new role eb-service-role-joru. This is assigned to the Elastic Beanstalk manager. Use the managed policy: AWSElasticBeanstalkFullAccess and add the following trust relationship to the role.

aws iam create-role \
    --role-name eb-service-role-joru \
    --assume-role-policy-document file://./service-role-trust.json

aws iam attach-role-policy \
    --role-name eb-service-role-joru \
    --policy-arn arn:aws:iam::aws:policy/AWSElasticBeanstalkFullAccess

Create a new role eb-instance-role-joru. This is assigned to each individual instance.

aws iam create-role \
    --role-name eb-instance-role-joru \
    --assume-role-policy-document file://./instance-profile-trust.json

aws iam create-instance-profile \
    --instance-profile-name eb-instance-profile-joru

aws iam add-role-to-instance-profile \
    --instance-profile-name eb-instance-profile-joru \
    --role-name eb-instance-role-joru
# creates the app specification to AWS and `.elasticbeanstalk` directory
# note that these are just defaults, `create` can overwrite any of these
eb init \
    --platform ruby-2.2-(puma) \
    --region us-west-2 \
    --keyname eb-joru

# each app has multiple app environments e.g. staging and prodution
# WebServer-Standard or Worker, serving or consumes queues?
# create the role first
# instance name is the same as environment name so include the app name
eb create \
    --service-role eb-service-role-joru \
    --instance_profile eb-instance-profile-joru \
    --instance_type t1.micro \
    --tier "WebServer-Standard" \
    --cname joru-staging-topaz \
    --scale 1 \


# To open the application in browser
eb open

# What is this? An error? Time to dig in...
eb logs
# There is a Rack error that `secret_key_base` is missing.
# You can see it missing yourself by looking at the env variables.
eb printenv
# Let's define it...
eb setenv SECRET_KEY_BASE=DOIGS15CB1xf5MRDx2kcklbPwEmtl691xChdp2NE

eb open
# Everything should be good now.

# To update the servers after changes:
eb deploy joru-staging-topaz


mkdir .ebextensions
cd .ebextensions
touch joru.config
  - option_name: RUKSI_API_KEY

# Run rake tasks before an application deployment
    #command: rake db:migrate
eb deploy joru-staging-topaz

# You can now see the new RUKSI_API_KEY in environment.
eb printenv