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
Add the custom recipe and click the plus icon (the recipe name is exaclty rails::dotenv
)
It should look like this
Click save in the lower right corner and update you custom cookbooks by clicking on Stack
and then Run command
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!