Heroku Builder allows for straight forward configuration of your multi (or single) stage Heroku application as well as dead simple deployment. It uses a YAML configuration to manage a multi-environment configuration, including: configuration variables, resources, add-ons, and git based deployment.
I wrote this gem to solve two particular problems I've found with Heroku. The first is constructing a new multi-environment application. Setting up a new app isn't hard in Heroku, but building backstage, staging, and production environments that each contain the same core resources, add-ons, and environment variables always resulted in me forgetting something, and spending time troubleshooting.
The second, and more common, is for managing environment variables through various stages. We use feature flags and environment variables heavily. This means a code deployment often requires environment variables to be set for features to work correctly. With Heroku Builder, a developer can set Heroku Config-vars in the project code. As the code moves through the various environments, deploying with rake builder:{environment-name}:apply
will set the Config-vars required for the code changes in addition to deploying code changes.
Treating configuration as code allows for peer review, versioning, and a historic view of an application's history. It more completely captures the essence of what is required to run an application.
Add this line to your Rails application's Gemfile:
gem 'heroku_builder'
And then execute:
$ bundle
Or install it yourself as:
$ gem install heroku_builder
Sinatra needs some extra configuration to ensure the rake tasks in the gem are available in your application. First, to the top of the Rakefile
file, load your environment variables:
require 'dotenv'
Dotenv.load
Next, add the following after Rake has been required:
require 'bundler'
Bundler.setup
Bundler.load.specs.each do |spec|
spec.load_paths.each do |load_path|
Dir.glob("#{load_path}/**/*.rake").each do |rake_file|
load rake_file
end
end
end
To get started, generate a new configuration file:
$ rake builder:init
This will place a file `config/heroku.yml with some basic configuration options. You'll want update the configuration files as you see fit for your particular setup. The configuration file is the meat of this tool, so let's take a look at what we can do with it.
When you open config/heroku.yml
, you'll see 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
Let's start from the outside and work our way in.
staging
and production
are references to the environments you maintain for a particular application. You can add as many of these as you'd like. These environments also determine the environment a Rake task targets. For example:
$ rake builder:staging:apply
Would apply the configuration for the staging
environment.
The app
sections provides settings particular to the application.
name
- the Heroku application name. The application will be created unless it already exists on Heroku.git_branch
- the branch of thegit_repo
repo that you wish to deploy from.
The config_vars
setting allows you to set Config Vars for a particular environment. These can be applied as follows:
config_vars:
FOO: bar
BAZ: <%= ENV['BAZ'] %>
Variables can be set with either a string or ERB tags. ERB tags allow sensitive information to be kept out of code that is committed. It's important to know that Heroku Builder only adds or updates variables that are defined in the configuration. Variables that are set in the Heroku console, but not defined in your configuration will not be removed.
The addons
section allows you to define the Add-ons for a particular application. Add-ons are defined as an array:
addons:
- papertrail
- heroku-postgresql:hobby-dev
- heroku-redis:hobby-dev
- scheduler:standard
As with other sections, be aware that removing add-on items will not cause them to be deleted from Heroku. Removing add-ons should be handled through the Heroku Dashboard.
The resources
section allows a user to define the resource types and counts. An example of a resource section for a side project might look like:
resources:
web:
count: 1
type: Free
worker:
count: 1
type: Free
For a production website, it might look more like:
resources:
web:
count: 8
type: 2X
worker:
count: 4
type: 1X
Heroku Builder requires a Heroku API key. Directions for generating a key are here: Heroku API Key
The gem will look for the key in the HEROKU_API_KEY environment variable. The key can be set either in your environment variable library (ex. dotenv):
# .env.local
HEROKU_API_KEY=xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx
or in front of the rake task:
HEROKU_API_KEY=xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx rake builder:staging:apply
Heroku Builder currently has two actions: apply
and deploy
.
$ rake builder:staging:apply
- Creates the application, if it has not been created
- Sets Config-vars (if there are changes)
- Deploys code (if there are changes)
- Configures Add-ons (if there are changes)
- Configures Resources (if there are changes)
As apply
only adds or updates when your heroku.yml
file has changes, it's safe to always use apply
to deploy code. Alternatively, you can just run the deploy
portion.
$ rake builder:staging:deploy
- Switches to the branch for that environment
- Pulls down any remote changes
- Creates a remote for Heroku, if the remote is not present
- Pushes to that remote
The environments defined in your heroku.yml
file provide scope for the Heroku Builder rake tasks. If you have the following:
foo:
...
bar:
...
The four rake options would be:
$ rake builder:foo:apply
$ rake builder:foo:deploy
$ rake builder:bar:apply
$ rake builder:bar:deploy
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/jvanderhoof/heroku_builder. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.