Deploying a Rails 5 App using Elastic Beanstalk and PostgreSQL

Update 24/11/17

James Hamann
7 min readJun 29, 2017

--

I’ve recently published a post on deploying a Rails 5 API app with React on AWS Elastic Beanstalk, click here to read!

In the past I’ve done post involving AWS and about how to deploy your website using AWS and Jekyll. Seeing as they just had their annual Summit in London (which was great by the way), I figured I’d do a post on how to deploy a simple Rails app, that uses postgres, on Elastic Beanstalk.

What is Elastic Beanstalk?

EB or Elastic Beanstalk, allows users to quickly deploy and manage their applications without having to worry about configuring the infrastructure that runs those applications. It takes care of load balancing, health monitoring, capacity provision and scaling, which allows you to focus on your actual application a little more. At the moment, it supports applications developed in Java, PHP, .NET, Python, Node.js and Ruby. The great thing with EB is that it allows you to manage different environments under a single application. For example, you could test new features or plug-ins, live, on staging, without effecting your production site, which is pretty useful. If you’re used to deploying on Heroku, Elastic Beanstalk is kind of the same thing. Refer to the AWS free tier guide, if you’re unsure about potential charges.

Getting Started

It probably goes without saying, but make sure you have an AWS account. Next, assuming you have brew installed, make sure to update it and then download the CLI for EB.

$ brew update
$ brew install awsebcli
$ eb --version
EB CLI 3.2.2 (Python 3.4.3)

To ensure it’s all correctly installed, just run the version command and you should get something resembling the above.

I’m going to assume you’ve got your rails app ready to go, in the sense that it works locally and you’re looking to just deploy it. With this in mind, in your app directory you’re going to want to initialise EB.

$ eb init

After running the above command, you’ll be presented with a set of questions regarding the app, the first of which about which zone you’d like to set up in.

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) us-east-2 : US East (Ohio)
14) ca-central-1 : Canada (Central)
15) eu-west-2 : EU (London)
(default is 3):

As I’m in London, I’d obviously choose 15, but choose which ever zone is closest to where you are.

Select an application to use
1) AnotherAppIPreviouslyDeployed
2) [ Create new Application ]
(default is 2): 2
Enter Application Name
(default is "myapp"):
Application myapp has been created.
It appears you are using Ruby. Is this correct?
(Y/n): y
Select a platform version.
1) Ruby 2.3 (Puma)
2) Ruby 2.2 (Puma)
3) Ruby 2.1 (Puma)
4) Ruby 2.0 (Puma)
5) Ruby 2.3 (Passenger Standalone)
6) Ruby 2.2 (Passenger Standalone)
7) Ruby 2.1 (Passenger Standalone)
8) Ruby 2.0 (Passenger Standalone)
9) Ruby 1.9.3
(default is 1): 1
Do you want to set up SSH for your instances?

It will then ask you which application to use, you’d select a new application, I’ve got two options as I’ve deployed something already. Next you can change the name of your app, but it’ll choose the app’s root by default. The Beanstalk will even check what your app’s written in and make a presumption, but it’ll still confirm it with you first. Next you’re going to want to choose a ruby platform that matches your ruby version used for your app.

The last option allows you to set up SSH for your instances if you want to remotely connect and configure stuff, it’s not long to setup and will just generate a keypair for you to use, which is then automatically uploaded to your generated instance on the EB console. If you want to keep things simple for now, just hit no.

Setting up the Enviornment

Now if you log into your AWS console and head over to Elastic Beanstalk, you’ll see your created app just sitting there. It’s all ready to go, we just need to actually upload our code.

First thing to do is to create an environment.

$ eb create myapp-env

Next EB will do some magic and create everything you need for your environment, this includes an S3 bucket to store environment data, a security group, a load balancer, an auto-scaling group and CloudWatch alarm notifications.

Creating application version archive "app-170629_125010".
Uploading myapp/app-170629_125010.zip to S3. This may take a while.
Upload Complete.
Environment details for: myapp-env
Application name: myapp
Region: eu-west-2
Deployed Version: app-170629_125010
Environment ID: e-r4aeg3mdhp
Platform: arn:aws:elasticbeanstalk:eu-west-2::platform/Puma with Ruby 2.3 running on 64bit Amazon Linux/2.4.1
Tier: WebServer-Standard
CNAME: UNKNOWN
Updated: 2017-06-29 11:50:15.449000+00:00
Printing Status:
INFO: createEnvironment is starting.
INFO: Using elasticbeanstalk-eu-west-2-677471806624 as Amazon S3 storage bucket for environment data.
INFO: Created security group named: sg-6aa8d203
INFO: Created load balancer named: awseb-e-r-AWSEBLoa-1HFNDWZGG06GC
INFO: Created security group named: awseb-e-r4aeg3mdhp-stack-AWSEBSecurityGroup-4BVER9RZTAEA
INFO: Created Auto Scaling launch configuration named: awseb-e-r4aeg3mdhp-stack-AWSEBAutoScalingLaunchConfiguration-BGBXSRWXV2CS
INFO: Environment health has transitioned to Pending. Initialization in progress (running for 30 seconds). There are no instances.
INFO: Created Auto Scaling group named: awseb-e-r4aeg3mdhp-stack-AWSEBAutoScalingGroup-16TMUTO9XH2LD
INFO: Waiting for EC2 instances to launch. This may take a few minutes.
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:eu-west-2:677471806624:scalingPolicy:3554965a-0856-4f3c-90be-cb49bace9305:autoScalingGroupName/awseb-e-r4aeg3mdhp-stack-AWSEBAutoScalingGroup-16TMUTO9XH2LD:policyName/awseb-e-r4aeg3mdhp-stack-AWSEBAutoScalingScaleUpPolicy-1NDWK7HFTSWWT
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:eu-west-2:677471806624:scalingPolicy:2e1bac83-9f60-41ca-b60d-70e83fe14992:autoScalingGroupName/awseb-e-r4aeg3mdhp-stack-AWSEBAutoScalingGroup-16TMUTO9XH2LD:policyName/awseb-e-r4aeg3mdhp-stack-AWSEBAutoScalingScaleDownPolicy-56CUZI6KKCGU
INFO: Created CloudWatch alarm named: awseb-e-r4aeg3mdhp-stack-AWSEBCloudwatchAlarmHigh-MXF54IOA2SZX
INFO: Created CloudWatch alarm named: awseb-e-r4aeg3mdhp-stack-AWSEBCloudwatchAlarmLow-V88MV4MSDP3H
INFO: Added instance [i-0086bb04a1a0d57b9] to your environment.
INFO: Environment health has transitioned from Pending to Ok. Initialization completed 27 seconds ago and took 3 minutes.
INFO: Successfully launched environment: myapp-env

It doesn’t take too long but it gets everything nicely setup and ready to go. To check it’s all working, you can view the status, like below.

$ eb status 
Environment details for: myapp-env
Application name: myapp
Region: eu-west-2
Deployed Version: app-170629_125010
Environment ID: e-r4aeg3mdhp
Platform: arn:aws:elasticbeanstalk:eu-west-2::platform/Puma with Ruby 2.3 running on 64bit Amazon Linux/2.4.1
Tier: WebServer-Standard
CNAME: myapp-env.itykuuzig2.eu-west-2.elasticbeanstalk.com
Updated: 2017-06-29 11:54:30.354000+00:00
Status: Ready
Health: Green

Last thing to do for the Rails App, is to generate a new SECRET_KEY_BASE environment variable to use, which is pretty simple to do.

$ rake secret
generatesalongkey

Next, you’re going to want to update EB’s environment variables, it’s important to note that, similar to Heroku, you’re going to have to set all your environment variables again, as your now running on a totally different machine.

$ eb setenv SECRET_KEY_BASE=generatesalongkey

This will update the environment with the new environment variable. The process is the same for any other env vars you may have.

Setting up PostgreSQL with Rails on your Instance

So your app probably still won’t run at this point, as we haven’t actually setup a database for it. That’s alright, we’re about to do it now.

Head over to your app’s dashboard on the Elastic Beanstalk console and hit the “Configuration” Tab.

Then at the bottom of the page you’ll see the following.

Hit the “create a new RDS database” link and follow the instructions.

Choose a secure username and password, then hit apply. This will create the database for you.

We also need to tell our instance to use postgres, and in order to do this we use a yum package called postgresql93-devel.

You can create custom configurations for EB environments, all you need to do is create a .ebextensions folder in the root, and then name the file anything you want with the suffix .config. The file should also be formatted like a .yml file. In this case, your db.config file will look like this.


packages:
yum:
postgresql93-devel: []

Now commit and push this update to your repo and then re-deploy the latest version of your app.

$ git add .
$ git commit -m 'adding .config for postgres setup'
$ git push origin master
$ eb deploy

Once this is done, you can open up your web app with the following command.

$ eb open

Everything should now be setup and working!

If you have any questions, or need any help, please do leave a comment or shoot me a message and I’d be happy to help!

Thanks for reading, hit 💚 if you like what you read and be sure to follow to keep up to date with my future posts.

--

--