Skip to content

jvanderhoof/heroku_builder

Repository files navigation

Heroku Builder

Gem Version Code Climate

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.

Why

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.

Installation

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

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

Usage

Getting Started

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.

Configuration

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 the git_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 API Key

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

Running Rake Tasks

Heroku Builder currently has two actions: apply and deploy.

Apply

$ rake builder:staging:apply

  1. Creates the application, if it has not been created
  2. Sets Config-vars (if there are changes)
  3. Deploys code (if there are changes)
  4. Configures Add-ons (if there are changes)
  5. 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.

Deploy

$ rake builder:staging:deploy

  1. Switches to the branch for that environment
  2. Pulls down any remote changes
  3. Creates a remote for Heroku, if the remote is not present
  4. 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

Development

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.

Contributing

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.

License

The gem is available as open source under the terms of the MIT License.

About

Dead simple multi-environment Heroku setup.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published