Skip to content

wiscoDude/chamber

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chamber Build Status Code Climate

Chamber lets you source your Settings from an arbitrary number of YAML files and provides a simple mechanism for overriding settings from the ENV, which is friendly to how Heroku addons work.

Installation

Add this line to your application's Gemfile:

gem 'chamber'

And then execute:

$ bundle

Or install it yourself as:

$ gem install chamber

Usage

The following instructions are for a Rails app hosted on heroku with both staging and production heroku environments.

Create a Settings class that extends Chamber in app/models/settings.rb:

class Settings
  extend Chamber
end

Create a config/settings.yml that has this structure:

# specify environment your Rails app is running in
development:
  # In development, we manually set the value to the variable we'll use
  # Settings.REDIS_TO_GO -> returns the URL
  REDIS_TO_GO: "redis://root@localhost:6379"

production:
  # In production, on Heroku, for example
  # Settings.REDIS_TO_GO -> looks for the variable in the ENV and returns its value
  REDIS_TO_GO:
    environment: "REDISTOGO_URL"

Call source in your Settings class:

class Settings
  extend Chamber

  source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
end

Add environment-specific files for development and test to supply the values for those environments. Make sure to add these to .gitignore.

Add another call to source for these files:

class Settings
  extend Chamber

  source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
  source Rails.root.join('config', "credentials-#{Rails.env}.yml")

  load!
end

Finally, after all your source calls, you must call load!:

class Settings
  extend Chamber

  source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
  source Rails.root.join('config', "credentials-#{Rails.env}.yml")

  load!
end

Use heroku config to set the ENV_VAR_NAME value for the staging and production remotes.

Now you can access your settings in your code as properties of your Settings class (assuming you extended Chamber in a class named Settings).

In other words, given a configuration file like this:

s3:
  access_key_id: value
  secret_access_key: value
  bucket: value

the corresponding Paperclip configuration would look like this:

Paperclip::Attachment.default_options.merge!(
  storage: 's3',
  s3_credentials: {
    access_key_id: Settings.s3.access_key_id,
    secret_access_key: Settings.s3.secret_access_key
  },
  bucket: Settings.s3.bucket,
  ...

General Principles

Support best practices with sensitive information

Generally this is expressed in this overly simplified form: "Don't store sensitive information in git." A better way to say it is that you should store sensitive information separate from non-sensitive information. There's nothing inherently wrong with storing sensitive information in git. You just wouldn't want to store it in a public repository.

If it weren't for this concern, managing settings would be trivial, easily solved use any number of approaches; e.g., like using YAML and ERB in an initializer.

I recommend adding a pattern like this to .gitignore:

# Ignore the environment-specific files that contain the real credentials:
/config/credentials-*.yml

# But don't ignore the example file that shows the structure:
!/config/credentials-example.yml

You would then use Chamber like this:

class Settings
  extend Chamber
  source Rails.root.join('config', "credentials-#{Rails.env}.yml")
end

Support arbitrary organization

You should be able to organize your settings files however you like. You want one big jumbo settings.yml? You can do that with Chamber. You want a distinct settings file for each specific concern? You can do that too.

Chamber supports this by allowing:

  • Arbitrary number of files:
class Settings
  extend Chamber

  source Rails.root.join('config', 'settings.yml')
  source Rails.root.join('config', 'facebook.yml')
  source Rails.root.join('config', 'twitter.yml')
  source Rails.root.join('config', 'google-plus.yml')
end
  • Environment-specific filenames (e.g., settings-#{Rails.env}.yml)

  • Namespaces:

class Settings
  extend Chamber

  source Rails.root.join('config', 'settings.yml'), namespace: Rails.env
end

Support overriding setting values at runtime from ENV

heroku addons are configured from ENV. To support this, Chamber's source method provides an override_from_environment option; e.g.,

class Settings
  extend Chamber

  source Rails.root.join('config', 'settings.yml'), override_from_environment: true
end

Ideas

  • Add a rake task for validating environments (do all environments have the same settings?)

  • Add a rake task for setting Heroku environment variables.

Alternatives

figaro

figaro

idkfa

idkfa

settingslogic

settingslogic

Others?

I'd love to hear of other gems and/or approaches to settings!

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Ruby 100.0%