AWS

How to Deploy your Rails App as easy as Heroku?


Reading Time: 5 minutes

Imagen relacionadaThis is your situation:

You have this new shining and beautiful rails app which you have been working on for a couple of weeks or months. It’s like your baby and you’re eager to show it to the world. You followed the best practices from the ruby and rails worlds, and even you prepared it to support a lot of users.

However, just when you’re almost ready to manage the fame and success with your app, you discover you’re missing an important fight to tackle; the complicated and scary deployment to a cloud server.

You already know there are some solid solutions, such as ANSIBLE or Capistrano, but you do not have time to learn how to use them. So, it is not an option right now.

Worry no more, today we are going to learn how to deploy your rails app in a few steps ( as easy as Heroku) with the help of AWS Beanstalk.

AWS Elastic Beanstalk is an orchestration service offered by Amazon Web Services for deploying your application which orchestrates various AWS services, including EC2, S3, Simple Notification Service (SNS), CloudWatch, autoscaling, and Elastic Load Balancers.

And a nice thing more:

**There is no additional charge for Elastic Beanstalk ,  you only pay for the AWS resources needed to store and run your applications.**

You will need:

So, let’s start:

For this first post, we are going to use the most basic tools of the CLI, and in subsequent posts, we are going to learn how to customize the process.

Once you have set up your AWS account, we need to install the AWS CLI, run the following commands in your terminal:

brew update

brew install aws-elasticbeanstalk

When the installation of these components is ready, let’s prepare our app.

Run this in your terminal:

cd your_project/
eb init

This command will guide you through a series of steps to configure your project to be deployed.

Before you start, make sure you have your AWS credentials. You can follow these steps to get them.
https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys

You have not yet set up your credentials or your credentials are incorrect.
You must provide your credentials.
(aws-access-id): AKIAJOUAASEXAMPLE
(aws-secret-key): 5ZRIrtTM4ciIAvd4EXAMPLEDtm+PiPSzpoK

You can also set them as env vars in your current MacOs user in order to avoid setting them every time.

So eb init will display this on your terminal:

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) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
(default is 3):

Choose the region that you prefer and press enter (generally you choose the region based on the proximity to you or to your end users).

The next step is to create the app in AWS( the cli will show you apps previously deployed) If this is the first time you configure your app, choose option 2.

Select an application to use
1) previous-app-book
2) [ Create new Application ]

Now, choose how you will identify your app in AWS. Leave blank if you want to use the default name.

Enter Application Name
(default is "beanstalk_app_example"):

Beanstalk will detect the language used, in our case, Ruby is correct:

It appears you are using Ruby. Is this correct?
(Y/n):

Now you need to choose which platform suits the best your Rails version. For this example I will use the default one:

Select a platform version.
1) Ruby 2.6 (Passenger Standalone)
2) Ruby 2.6 (Puma)
3) Ruby 2.5 (Passenger Standalone)
4) Ruby 2.5 (Puma)
5) Ruby 2.4 (Passenger Standalone)
6) Ruby 2.4 (Puma)
7) Ruby 2.3 (Passenger Standalone)
8) Ruby 2.3 (Puma)
9) Ruby 2.2 (Passenger Standalone)
10) Ruby 2.2 (Puma)
11) Ruby 2.1 (Passenger Standalone)
12) Ruby 2.1 (Puma)
13) Ruby 2.0 (Passenger Standalone)
14) Ruby 2.0 (Puma)
15) Ruby 1.9.3
(default is 1):

Beanstalk will show you this message offering their source control service. I have my repo in github, so I will not use it this time.

Note: Elastic Beanstalk now supports AWS CodeCommit;
a fully-managed source control service. To learn more, see Docs: https://aws.amazon.com/codecommit/
Do you wish to continue with CodeCommit? (y/N) (default is n): n

Next step is to configure your SSH access. I will create a new one:


Do you want to set up SSH for your instances?
(Y/n): Y

Select a keypair.
1) aws-prev-app
2) [ Create new KeyPair ]
(default is 1): 2

Type a keypair name.
(Default is aws-eb): aws-beanstalk-example

You will get an output similar to this:

Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/aws-beanstalk-example.
Your public key has been saved in ~/.ssh/aws-beanstalk-example.pub.
The key fingerprint is:
...
WARNING: Uploaded SSH public key for "aws-beanstalk-example" into EC2 for region ....

Let’s Deploy

Now, the moment your app has been waiting for its whole life, the deployment: 

We are going to create the required environments (dev, staging, production).

For this example, I will go directly to create production. (DO NOT try this at home kids)

Enter in your console the next command:

eb create production

Now Beanstalk will prepare everything for you, load balancers, security groups, EC2 server, etc.

2019-04-30 22:59:22    INFO    createEnvironment is starting.
2019-04-30 22:59:23    INFO    Using ~-us-west-2-67584136 as Amazon S3 storage bucket for environment data.
2019-04-30 22:59:43    INFO    Created security group named: sg-fsdfsdf222xxxx
2019-04-30 22:59:58    INFO    Created load balancer named: awseb-e-mWfxxxxxxSEBLoa-HAVKQBQMaX
2019-04-30 22:59:58    INFO    Created security group named: awseb-e-mexxxxv-stack-AWSEBSecurityGroup-1xxxx
2019-04-30 22:59:58    INFO    Created Auto Scaling launch configuration named: awseb-e-mxxxxxqnmv-stack-AWSEBAutoScalingLaunchConfiguration-1xxxxxx
2019-04-30 23:01:32    INFO    Created Auto Scaling group named: awseb-e-merrq7qnmv-stack-AWSEBAutoScalingGroup-1xxxxx
2019-04-30 23:01:32    INFO    Waiting for EC2 instances to launch. This may take a few minutes.

Don’t forget to set the required environment variables, for this example, I will set the rails secret env.

eb setenv SECRET_KEY_BASE=$(rails secret)

If everything went well, the CLI should show you all the details of your app and the URL where you can check it. Yay! Congrats!

Troubleshooting

At this moment, you could also receive some errors when running the process.
Example:
Your Ruby version is 2.6.3, but your Gemfile specified 2.3.4.

Don’t worry, change everything you need before trying again.
And when you’re ready just run eb deploy.

If you want to check the logs into more details, you can do it as easy as:

eb logs

To know more about your deployed app, do this:

eb status


Database Configurations

What is a rails app without a database?
Let’s configure it.
I am using PG for this example, but you should not have any problems with other DB engines.

First, add this configuration to your env configuration in your database.yml.
For my specific case, I’ll set up ‘production’:

production:
    <<: *default
    adapter: postgresql
    encoding: unicode
    database: <%= ENV['RDS_DB_NAME'] %>
    username: <%= ENV['RDS_USERNAME'] %>
    password: <%= ENV['RDS_PASSWORD'] %>
    host: <%= ENV['RDS_HOSTNAME'] %>
    port: <%= ENV['RDS_PORT'] %>

After this, you need to log in your AWS console.

Beanstalk will set the required env vars for the DB, so you do not need to worry about it.

After deploying your app, it should be running in your new AWS server. Congrats once again!

Resultado de imagen para that's all for now folks

Thank you, on the next posts, we will learn how to customize things and combine this process with docker and some other tricks.

Advanced Level
Fixing Rspec and Cucumber random failures in your Continuous Integration Service
Best Practices
De Código, Café y Cervezas 10 – Technical Debt
Rails
ActiveRecord::Observer