Deploying Rails 4 + PostgreSQL to AWS OpsWorks

Recently we decided to move one of our Ruby on Rails applications off Heroku and onto AWS. After some experimentation, we settled on AWS OpsWorks. OpsWorks is billed as an integrated DevOps application management solution and it allows a high degree of control over the application deployment strategies as well as support for task automation. Because AWS OpsWorks supports Chef recipes, you can leverage hundreds of community-built configurations such as PostgreSQL, Nginx, and Solr. In our case, the out-of-the-box support for Ruby on Rails, coupled with Chef and a PostgreSQL RDS instance made the switch from Heroku fairly simple. While there are many factors that go into choosing an application management solution, a big factor for us was the ability to leverage Virtual Private Clouds (VPC) within OpsWorks for HIPAA compliancy. This post is a broad overview covering the basics of how we achieved this, and later posts will dig into more details.

Initially, we’ll want to login to the AWS OpsWorks dashboard and add a Stack. In short, a stack is a set of instances and related resources whose configuration you want to manage together.

Add Stack

All stacks will be composed of one or more Layers, each of which represents an application component, such as a load balancer, an application server and a service layer.

For our application server layer, we chose the Rails App Server AWS OpsWorks Layer. This layer is where we will install and configure our rails app. Functionally, this layer acts as a pointer to a repository, in our case a git repo.

Add App

For our service layer, we chose Amazon’s Relational Database Service using PostgreSQL.

Lastly, our stack’s layers need an Instance to run on. Instances are EC2 VMs that will host and run our application layers. After you create a layer, you usually need to add at least one instance.

Security/Permission requirements and application specific configurations are outside of the scope of this post, but we had a small hiccup using Postgres initially. Presently, the OpsWork deployment has/had a small bug where the database.yml file is created incorrectly, dropping Postgres as the adapter and reverting to MySQL (see more here). In order to get a working database.yml file created and deployed onto your production server through OpsWorks, you’ll most likely need to pass a custom JSON hash into the application layer’s Custom JSON field before deploying.

Ours looked like this:

  "deploy": {
    "myappname": {
      "database": {
        "adapter": "postgresql",
        "encoding": "unicode",
        "host": "",
        "port": "5432",
        "database": "mydatabase",
        "pool": "5",
        "username": "secretusername",
        "password": "secretpass"

While the community documentation on setup and deployment out there is a bit lacking, AWS OpsWorks overall was a concise tool that allowed us to easily manage our infrastructure and automate our application deployments, leaving us free to focus on developing quality software for our clients.

James Denman

James Denman

VP of Technology

James Denman is the VP of Technology at Levvel and is located in Sydney, Australia. He has over 10 years of experience working in the Defense, Diplomatic, and NGO technology sectors across more than 12 countries.