AWS Developer Blog

Deploying Ruby on Rails Applications to AWS OpsWorks

by Alex Wood | on | in Ruby | | Comments

To begin our series on using Ruby on Rails with Amazon Web Services, we are going to start at the beginning: deploying our application. Today, we will be deploying our application to AWS OpsWorks.

Following along with this post, you should be able to deploy our "Todo Sample App" to AWS using OpsWorks, with your application and database running on different machine instances.

Getting Your Application Ready to Deploy

You can deploy the Todo sample application to OpsWorks directly from its public GitHub repo, using the ‘opsworks’ branch. If you explore the repo, you will notice that we’ve made a few design choices:

  • Our secrets file at config/secrets.yml expects the RAILS_SECRET_TOKEN environment variable to be set on our application servers.
  • We have required the mysql2 gem, to interface with a MySQL database.
  • We have required the unicorn gem, and will use unicorn as our app server.

Creating an OpsWorks Stack

Log in to the AWS Console and navigate to the AWS OpsWorks Console. Click Add Stack and fill out the form like so:

Add Stack Screen

Don’t worry about the "Advanced" settings for now – we won’t need them during this part of the tutorial. Once you’ve filled out the form, just press Create Stack and you’re done.

Creating the Rails App Server Layer

After creating a stack, you’ll find yourself at a page prompting you to create a layer, an instance, and an app. To start, click Add a layer.

We are making a few changes to the default options here. They are:

  • Using Ruby version 2.1.
  • Using "nginx and Unicorn" instead of "Apache2 and Passenger".
  • Using RubyGems version 2.2.1.

Once you’re all done, click Add Layer. You’ll be redirected to the "Layers" screen.

Creating the Database Layer

Next, we’re going to create our database layer. On the layers screen, click + Layer.

Add MySQL Layer

Choose "MySQL" from the drop down box, and leave everything else as-is. Of course, if you’re taking your own screenshots, it is best to avoid sharing your passwords of choice as well!

Click Add Layer and you’re done with this step.

MySQL Layer vs. Amazon RDS Layer

When creating your stack, you can choose to use an OpsWorks-managed EC2 instance running MySQL, called a "MySQL" layer, or you can create a layer that points to an existing Amazon RDS instance.

For this example, we are going to use a MySQL layer. You could substitute an RDS layer if you so chose. In future posts, we may explore this option in depth.

Adding Instances

We’ve made layers for our application servers and database, but we do not yet have application servers or a database. We will next create an instance of each.

Create an App Server Instance

From the "Layers" screen, click Add instance in the "Rails App Server" layer.

Add Rails Instance

We’re creating a t2.micro instance to optimize for cost (this is a demo after all). You may also want to create an SSH key and specify it here in order to be able to log in to your host for debugging purposes, but we don’t strictly need it so we are going to skip that for now.

Click Add Instance once you’re done, then start to begin the instance setup process. While that runs, we are going to make our database instance.

One quick aside about using a t2.micro instance: you can only create them in a VPC. We have created a VPC in this example, but if you were creating a stack without a VPC, t2.micro instances will not be available to you. Other instance types will, of course, work for this example.

Create a Database Instance

You’ll note that, if you’re following along with each step, you’re now at the "Instances" page. From either here or the layers page, under "MySQL", click Add an instance.

Add MySQL Instance

As before, we are creating a t2.micro instance. Click Add Instance to create the instance, and start to begin instance setup.

Adding the Application

While our instances are set up, let’s add our application. Click the Apps link on the sidebar, then click Add an app.

Add App

For this example, we’re using the Git repository at https://github.com/awslabs/todo-sample-app.git as our Application Source, and using the opsworks branch to ensure that you’re deploying the same code I was as this post was written. You can name the app whatever you’d like, but the "TodoApp" name will match with fields we will fill out later, so if you do change the name, make sure to use that new name going forward wherever we use "TodoApp".

Add App

To generate a value for the RAILS_SECRET_KEY environment variable, you can use the command rake secret within your copy of the repo. Just remember to set this as a "Protected value", and if you’re taking screenshots of your process, this is a good time to remove the placeholder value you used for the screenshot and to add a new value generated with rake secret.

Click Add App when you are done.

Deploying the Application

It is likely that your instances are done being created and set up by now, but double check that they are both online before continuing to this step. If by chance they are not quite set up, by the time you prepare a cup of tea and come back, they should be ready.

Click the Deployments link on the sidebar, then click the Deploy an App button.

Deploy App

Since we have not done so yet, remember to check "Yes" for the "Migrate database" setting. We will also need this custom JSON to ensure the "mysql2" adapter is used as intended:

{
  "deploy":
  {
    "todoapp":
    {
      "database":
      {
        "adapter": "mysql2"
      }
    }
  }
}

Click Deploy, and grab another cup of tea. You’ve now deployed the Ruby on Rails "Todo" sample app to AWS OpsWorks!

Use Custom JSON for All Deployments

You probably don’t want to be filling in the custom JSON for your adapter choice with every deployment. Fortunately, you can move this custom JSON into your stack settings to have it go with every deployment.

Click the Stack link on the sidebar, open Stack Settings, and click Edit.

Stack Settings

Add the custom JSON you used for your deployment earlier, and click Save.

Try It Out

To view the app in action, click on your app server’s name on the deployment screen to go to the server’s info page. Click the link next to "Public DNS", and you should see the front page of the application:

You can add tasks, mark them complete, and delete them as you like. In short, your application is running and performing database transactions.

Hello TodoApp!

Wrap-Up

In this post, we started with a Ruby on Rails application, and went step-by-step through the process to get it up and running on AWS with OpsWorks. Now, you can follow this same process to get your own Rails application running on AWS.

Now that we can deploy our application, we will begin to explore ways to make our app scale, improve availability, and optimize some common speed bottlenecks.

Have any questions, comments, or problems getting the app up and running? Suggestions for topics you would like to see next? Please reach out to us in the comments!