How to use Environment Variables on Engine Yard with Envyable

If you’re building an application in this day and age, chances are that you’re following methods from the Twelve-Factor App. One of these is to store configuration in the environment versus hard-coding them in your application.

With Engine Yard, it’s typically recommended that you write some custom Chef to modify your environment. If you’re only dropping in configuration files, like the secrets.yml file that Rails uses, Chef is a bit of an overkill. An easier way is to use the Envyable gem to load environment variables when the application is started.

Before we look at Envyable, let’s see some environment variable usage in a typical Rails application.

Rails Environment Varariables

I have a pretty basic Rails 4.2 app that uses the config/secrets.yml file to set the secret_key_base option. Here’s what it looks like:

# config/secrets.yml
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

On the server, you can then export a value for the SECRET_KEY_BASE variable and the application should pick it up.

$ export SECRET_KEY_BASE=4cd450125...763a705d1d6d2cc

However, when you have multiple servers that all need these values set, doing them manually is not a viable option. This is where Envyable really helps out.

Envyable

The Envyable library allows you to specify your environment variables in a file that is then loaded along with your application code. Instead of setting variables by hand or using configuration management to write config files, you can stick everything in the config/env.yml file. As long as it’s available on the server, your variables can be called in the application.

To use Envyable, you will need to add it to your application dependencies. Check the documentation for more info. After adding it to your app, you just need to create a config/env.yml file with your environment variables.

For our use case, the env.yml file would look like the following:

# config/env.yml
production:
  SECRET_KEY_BASE: 4cd450125...763a705d1d6d2cc

Using this with Engine Yard

After your application is set up with Envyable, you can then use it on Engine Yard.

I’ve got an application and environment setup already and I’ve pushed the change with Envyable added to the dependencies. I haven’t committed the env.yml file to the repo so, right now, the application won’t work as the secret_key_base option is not being properly set.

This is the environment configured on Engine Yard

Application error because the secret_key_base is not set

To get the env.yml file to the running environment, I’m going to use the engineyard gem. Version 3.0 of the gem has an scp command that will use the system scp to securely copy files to or from your instances.

You can get help with the command by running:

ey help scp

We can use this command to push the env.yml file to all of the servers:

$ ey scp config/env.yml HOST:/data/rails_app/shared/config/env.yml -e rails_app_prod
Loading application data from Engine Yard Cloud...
Copying 'config/env.yml' to 'HOST:/data/rails_app/shared/config/env.yml' on 1 server serially...
# solo ec2-50-19-211-19.compute-1.amazonaws.com
env.yml                                       100%   66KB  65.7KB/s   00:00

Note that I’m copying it to the shared/config directory. This is because when the code is deployed, it will automatically be symlinked into the config directory of the current deployment. It also has the added benefit of being on the /data partition which is periodically snapshotted. Hence, if you need to add more servers, the file will already be there when they spin up.

Now that the env.yml file is in place, we just need to run a deploy to pull in the new code and restart the application servers:

$ ey deploy
Loading application data from Engine Yard Cloud...
Using current HEAD branch "master".
Beginning deploy...
[...]
+    32s  ~> Skipping maintenance page. (no-downtime restarts supported)
+    32s  ~> Symlinking code.
+    32s  ~> Restarting app servers
+    32s  ~> Finished restarting app servers
+    32s  ~> Cleaning release directory: /data/rails_app/releases
+    32s  ~> Finished deploy at Thu Mar  5 18:59:07 2015
Saving log... Successful deployment recorded on Engine Yard Cloud.
Run `ey launch` to open the application in a browser.

If we load the application URL in the browser then we should be able to see the working application:

Rails App Welcome

Conclusion

That’s all there is to use environment variables with Ruby on Engine Yard. As you can see, with Envyable and the engineyard gem, the process is painless. If you want to check out the code, you can see it on GitHub.

P.S. What did you think about this post? Have any tips to share when it comes to managing environment variables and global application settings? Throw us a comment.

About Evan B. Machnic

I’ve been working with Ruby since 2008 and at Engine Yard since 2011. In my free time, I love stand-up paddle boarding, rock climbing and hanging out at the beach with my family.