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.
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.
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:
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.