Last Updated: February 25, 2016
·
924
· wstucco

Use the ENV Luke! (aka: simulate the ENV in OpsWorks using Chef and Dotenv)

OpsWorks is an impressive piece of software, but sometimes it lacks the comfort zone we developers love so much.
One feature that I really miss, is the ability to configure my application using ENV variables.
I'm not aware of any easy way (ie: Heroku like) to create environment variables in OpsWorks that the application can consume.

Fortunately OpsWorks is based on Chef and can be customized in any way you want.
Be warned, it's not always an easy path, basic Chef knowledge is required, the interface is quite convoluted, but in the end it gets the job done.

So, we were saying environment!
We know environment is not supported in OpsWorks, so what we really need is to simulate it in some way.
A common solution among Rails developers, is the Dotenv gem which load the file .env in the root of you app and create the correspondent keys in the ENV object.

I will assume you already have created a Stack in OpsWorks with a Rails application layer.

Rails side

Add the Dotenv gem to your Gemfile

gem 'dotenv-rails'

run bundle

$ bundle

as soon as possible, load the environment through Dotenv

# application.rb
require File.expand_path('../boot', __FILE__)
require 'dotenv'
Dotenv.load

push the new code to Github

OpsWorks side

From the Stack dashboard click on stack settings, select yes for Use custom Chef cookbooks, chose Git as repository type and insert https://github.com/mikamai/opsworks-dotenv as the repository URL.
If you wanna use a private repository, you also need to enter the SSH private key.
Choose your branch (master in this case) and add the following JSON in the Custom JSON box

{
  "deploy":{
    "your_app_name":{
      "symlink_before_migrate":{
        ".env" : ".env"
      },
      "app_env": {
        "YOUR_ENV_KEY": "KEY_VALUE",
        "ANOTHER_ENV_KEY": "SECOND_VALUE"
      }
    }
  }
}

Do not forget the symlink_before_migrate key, it tells Chef to link the .env file created in the shared deploy folder into
the current deploy folder, so that the Rails app can pick it up.

To retrieve the your_app_name value go to the Apps page in AWS console, click on the app name you want to configure and from there, copy the short name app property.

The last step is to instruct Chef to run your recipe on every deploy.
Click on the recipes link in the Rails layer section

OpsWorks layers

Add the custom recipe and click the plus icon (the recipe name is exaclty rails::dotenv)

Custom recipes

It should look like this

Custom recipes added

Click save in the lower right corner and update you custom cookbooks by clicking on Stack and then Run command

Update Custom Cookbooks

This step must be performed every time a recipe in the custom cookbook is added or updated.

You can now deploy your app and enjoy your shiny new ENV.

TL;DR: add Dotenv gem, clone https://github.com/mikamai/opsworks-dotenv, add it as Custom Chef Cookbook,
run rails::dotenv recipe on every deploy, be happy!