This 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:
- An existent AWS account (you can create one here: https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)
- A beautiful Rails App
- Terminal or any command line tool ( this tutorial is based on MacOS, but most of the commands will work in any OS with a little or none changes)
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.
- Go to https://us-west-2.console.aws.amazon.com/elasticbeanstalk/home?region=us-west-2#/welcome
- In the bar menu, look for your most recent app and go to configurations in the sidebar.
- Look for the database-configurations block and click on
Modify
- Select the desired database and apply changes. ( In our case, PG)
- Once ready, deploy your last rails app changes with an
eb deploy
and wait for the response.
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!
Thank you, on the next posts, we will learn how to customize things and combine this process with docker and some other tricks.