Deploying a Rails App to AWS OpsWorks using Chef 1211 Mar 2017
AWS OpsWorks is a configuration management service that uses Chef to automate server configurations. OpsWorks previously used Chef v11 and came with built-in cookbooks to deploy apps such as Rails, Node, and more. However, the latest OpsWorks Linux Chef v12 does not come with any built-in cookbooks. While this adds some more complexity to setting things up, it also comes with the added benefit of using community sourced cookbooks instead of ones developed by Amazon.
Our To-do List
- Download and install the Chef SDK on your local machine
- Create, package, and upload our local cookbooks to S3 (as per the AWS guides)
- Create a new Chef 12 OpsWorks Stack
- Deploy our Rails app
Creating a Chef Cookbook
On your local machine, create a new cookbook:
chef generate cookbook "my-cookbook" cd my-cookbook
Open up the freshly created
metadata.rb in a text editor. We’re going to use the fantastic opsworks_ruby set of cookbooks to emulate what OpsWorks did for us on Chef 11, when all you needed to do was choose “Rails App” from a dropdown menu.
# Berksfile source 'https://supermarket.chef.io' cookbook 'opsworks_ruby', '1.4.0' cookbook 'packages', '~> 1.0.0' metadata
# metadata.rb # -- ommitted metadata properties -- depends 'opsworks_ruby', '1.4.0' depends 'packages', '~> 1.0.0'
We’re also using the packages cookbook that can install OS packages such as
nodejs, or any other package your Rails app needs.
# recipes/default.rb node.default['packages-cookbook'] = [ 'nodejs', 'imagemagick' ]
Now we’re ready to package up these cookbooks and their dependencies. I recommend first installing the latest version of the
Berkshelf gem, as I ran into some issues with the installed version from the Chef SDK.
gem install berkshelf berks install berks package cookbooks.tar.gz
You should now find
cookbooks.tar.gz in your local directory; this archive contains all dependencies you’ve included in your
metadata.rb file, as well as all your dependencies’ dependencies. You’ll need to upload this file to an S3 bucket in your AWS account.
Creating a New OpsWorks Stack
Add your Rails App Layer
Here we enter our custom JSON generated from opsworks_ruby’s handy configurator. I’m using Unicorn as my app server, an RDS endpoint for my MySQL database, and Ruby version 2.3. I’ve also configured it to not migrate the database for each deployment, as I’d prefer to do that manually. Additionally, I have
assets_precompile disabled since I have that command running in a
before_restart.rb hook instead of running it along with the recipes. For more custom attributes, visit the opsworks_ruby documentation.
Configure Layer Recipes from the opsworks_ruby recipes
Create and Deploy Your Rails App
Creating an app in OpsWorks is fairly self-explanatory, so I won’t go in detail about that here. Once you get your app set up, you’re ready to spin up a new instance of your choosing and deploy your Rails app.
Automating Packaging and Uploading Your Cookbooks to S3
I’ve created a tool to automate this process so you don’t have to pull up the S3 web interface or use the AWS CLI. You can download it here.
I have most likely left out some details in this rather brief post, but this should get you going pretty quickly. All remaining setup will probably be unique to your application.