If you are using Rails, you are probably familiar with at least one YAML configuration:
config/database.yml. Many people took this example and ran with it, creating their own YAML configurations for Redis, Memcache and other services.
Here at 3scale we were pretty happy with this workflow, except for a few small things. Like for example what happens when you split your application into two? You have to load the configuration somehow in both. There is no code to load YAML files, you have to roll your own. What if you are using Sinatra? Or just plain Ruby without any framework? How do you handle deployment? Using Capistrano, right? But how do you share this YAML generation between projects?
Rails 4.2 will bring some sanity and provide
config_for for loading arbitrary YAML files. That is great if you’re running Rails 4.2. Unfortunately we’re not.
So we created a common framework for loading/uploading YAML configuration. Enter config_for.
It provides the following components:
- Rails integration
- Sinatra integration
- Capistrano 3 task
Let’s see them, one by one.
You won’t need to use these if you are using any of the integrations below. They are “low level” methods for loading, processing and parsing YAML configuration.
The common workflow for both is following: Read YAML file -> Process it by ERB -> Parse.
The bang version (
load_config!) will raise exception when your environment does not exist in the parsed hash.
Being low level, these methods need a full path to the folder with config files as well as the name of the config to load and the environment name.
This is probably only useful for applications using Rails < 4.2.
It hooks into the same place as the
config_for from Rails 4.2. So it provides an easy migration path. It will use your Rails config folder and environment (
Rails.env). Just like the other integrations, it is using
load_config! so it will raise exception when the environment is not found in the config.
Sinatra does not provide any method for loading config files by default, so this integration is especially handy. It is automatically loaded for classic apps, but for modular ones you have to register the plugin.
Now the juiciest part. If you have ever deployed a Rails app using Capistrano, you probably had to generate some YAML configuration. It probably was not a very nice experience.
Lets take a look on how easy it is to use a capistrano task for handing configuration. First it has to be loaded in
Now, you can use the
ConfigFor::Capistrano::Task to generate tasks for you.
That will generate several tasks in Capistrano, which you can use:
To persist the file between deployments, you have to add it to the
Advanced Capistrano patterns
You probably have other environments than production as we do. To make code reuse easier, we have a pattern for sharing some parts of configuration.
When you initialize
ConfigFor::Capistrano::Task.new(:name) it expects you to provide a variable named
name_yml. To reuse that variable between environments, we do:
That way you can have some defaults for all the environments and have less code in environment specific files.
And that’s it. Now whenever you
cap production deploy it will upload the
database.yml if missing. If you want to reset the configuration just run:
cap production database:reset and the configuration will be reset on all servers.
Hope you like the gem and it will make your deployment workflow a bit saner. Check the README for more examples.
We have been using this gem in production for about a month without any issues so far. If you have any feedback, please open an issue on Github.
Stay tuned, we will have some more goodies coming.