You cannot start a project without DiceBag the same way you can not setup your character without rolling dice.

The problem

Rails is very powerful and very configurable. The 3rd party gems you use in your project may all have their own configurations.

These files usually have a different configuration in the development environment than in production. For instance, you may not have memcache in development but have it in production. Even different stages of production (beta vs real users, etc.) may have different configurations.

Also we do not want to commit to the Git repository all the passwords and access keys to all the services an app is accessing.

There has not been one definite solution for this problem. There is a convention followed by some projects to name files with an extra .example extension and then engineers locally would use these files as base to setup the projects. Rails 4.2 has a new config/secrets.yml file to keep passwords out of the repository.

An additional problem is that given a project, once cloned, engineers need to know the conventions to run that project. They may need to refer to the README and if this is outdated they will need to ask some colleague or just figure it out their own. If the project does not run correctly, was it the configuration or was it a code problem?

At Medidata we have many projects and engineers are free to contribute to any of them. Thus it is important to have a standard way to configure both development and production environments.

The solution

DiceBag solves all these problems by providing a unique interface to configure projects.

DiceBag provides several rake task, the main one is ‘rake config’ which will read all the .dice files located anywhere in your project and generate configuration files from them. This way, when a new engineer wants to make a project work they only need to git clone the project and run rake config. At that point they know the project should be perfectly configured.

In production DiceBag reads its configuration from environment variables, keeping passwords and other configuration outside the git repository and following 12-factor principles.

This is an example of a database.yml.dice file:

<% [:development, :test, :production].each do |env| %>
<%= env %>:
  adapter: <%= configured[env].database_driver || 'mysql2' %>
  database: <%= configured[env].database_name || "myproject_name_#{env}" %>
  username: <%= configured[env].database_username || 'root' %>
  password: <%= configured[env].database_password %>
  host: <%= configured[env].database_host || 'localhost' %>
  pool: 5
  timeout: 5000
  encoding: utf8
  <% db_cert = configured[env].database_ssl_cert %>
  <%= db_cert ? "sslca: #{db_cert}" : '' %>
<% end %>

As you can see this file uses the Erb format to insert dynamic data into text.

Let’s look at one line of the lines:

adapter: <%= configured[env].database_driver || 'mysql2' %>

The object ‘configured’ let you access all the environments at the moment you executed DiceBag. In this case we are accessing the “DATABASE_DRIVER” environment variable. If this is not available then ‘mysql2’ will be used as a default parameter.

When we want to convert a .dice file to a real configuration file we run the next rake task:

$ rake config

This task will find all the .dice files in our project and will create configuration files. In this case it will create a database.yml file.

Typically the default values are valid for any development machine but we need to change them for production. To do that, we simply set environment variables in the server where we are deploying before running ‘rake config’.

For instance:

$ DATABASE_DRIVER='postgresql' rake config 

This follows the 12-factor principles and avoids any change in the code of the project to achieve changes in configuration. Also passwords and credentials can be kept in a different place and do not need to be committed to the Git repository.

Where to find it

The DiceBag repository is in https://github.com/mdsol/dice_bag, the rubygem can be found at http://rubygems.org/gems/dice_bag

Fully opensource and available for you to use.

Analytics