Heroku Builder can be leveraged two ways to improve your development and deploy workflow on Heroku: Config Variable management, and full app setup and management. As it’s far more likely you have an existing application, let’s start by looking at Config Variable management.
Before we begin, let’s install Heroku Builder. Add it to your Gemfile:
$ bundle install
Now, generated a configuration file (it will be placed in
$ rake builder:init
Open up the
config/heroku.yml file, and take a look. The contents will look something like this:
staging: app: name: my-heroku-app-name-staging git_branch: staging config_vars:  addons:  resources: web: count: 1 type: Free production: app: name: my-heroku-app-name git_branch: master config_vars:  addons:  resources: web: count: 1 type: Free
As we’re only managing Config Variables, remove
resources. You should end up with something like:
staging: app: name: my-heroku-app-name-staging git_branch: staging config_vars:  production: app: name: my-heroku-app-name git_branch: master config_vars: 
Update the staging app name and production app name to be that of your staging and production Heroku applications. If you don’t use ‘staging’ and ‘master’ for your staging and production branches, you should also update the git branches to match yours. If the staging application is called ‘foo-staging’ and the production application is called ‘foo’, your
config/heroku.yml file should look something like this:
staging: app: name: foo-staging git_branch: staging config_vars:  production: app: name: foo git_branch: master config_vars: 
Now let’s look at how you might use Heroku Builder to implement a feature flag. As a silly example, let’s look at using a feature flag to redirect to the index view rather than the show view after an object is created:
class BarsController < ApplicationController ... def create @bar = Bar.new(bar_params) if @bar.save redirect_to redirect_path else render :new, :status => :unprocessable_entity end end ... private def redirect_to_path if ENV.fetch('REDIRECT_TO_INDEX', 'false').match(/true|on/) bars_path else bar_path end end end
So now we have our feature completed, and tests (not included here) written, as well as had the code reviewed. Let’s make sure our feature flag is set in the heroku.yml:
staging: app: name: foo-staging git_branch: staging config_vars: - REDIRECT_TO_INDEX: on production: app: name: foo git_branch: master config_vars: - REDIRECT_TO_INDEX: on
The advantage to keeping environment configuration in source code is twofold. First, it allows configuration changes to be reviewed as part of the pull request development flow. The second advantage is that you can couple configuration changes with the code that requires it. When you deploy your code, you also deploy the configuration that code requires.
Assuming this code has been merged into our staging branch, let’s deploy it!
$ rake builder:staging:apply
This will set the Heroku Config Variables and deploy code from the head of your staging branch to the
foo-staging app on Heroku. Be aware that prior to pushing code to Heroku (using
git push), Heroku Builder will pull changes from the remote branch you’ve defined in the config file.
When it’s ready, deploying to production follows a similar pattern:
$ rake builder:production:apply
We can still do a bit of cleanup on our
config/heroku.yml file to DRY it up. Let’s use YAML node anchors to let us define common configuration:
config_defaults: &config_defaults REDIRECT_TO_SHOW: on SUPER_SECRET_KEY: <%= ENV['LOCAL_SECRET_KEY'] %> staging: app: name: foo-staging git_branch: staging config_vars: <<: *config_defaults production: app: name: foo git_branch: master config_vars: <<: *config_defaults
Now as our list of Config Variables grows, we don’t need to update them under each environment, we can set the global ones under
config_defaults and optionally override them in a particular environment. ERB tags are evaluated in the YAML file, so secret credentials can be stored locally without checking them into source control.
Hopefully this has given you a little insight into Heroku Builder and how you can use it to include project configuration in your project code base. In the next post, we’ll look at using Heroku Builder to create a multi-environment application on Heroku.