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.
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:
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.
Share your thoughts with @engineyard on Twitter