At OvrClk, we use Vagrant to develop and test our chef cookbooks and it has become an integral part of our workflow.

We also prefer checking in our knife config files in the SCM to reduce friction in setting up chef on our team members’ and clients’ workstations.

As a general rule, anything that is likely to change between development workstations–such as credentials for external services–we extract from the code into environment variables.

We wrote Vagrant ENV plugin to help us do that with ease. It lets you place environment variables in a .env, which are then made available to the Vagrantfile via ENV.

A sample Vagrantfile using the plugin could look like this, which is safe to share:

Vagrant.configure("2") do |config|
  config.env.enable = "dummy"
  config.vm.provider :aws do |aws, override|
    aws.access_key_id     = ENV['AWS_ACCESS_KEY']
    aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']

We built this plugin using dotenv, which can be accessed from any ruby file. A knife.rb config could look like:

current_dir = File.expand_path File.dirname(__FILE__)

  require 'dotenv'
rescue LoadError
  $stderr.puts <<-ERR
Could not load .env file because dotevn gem is missing.
Install it using `gem install dotenv` or `vagrant plugin install vagrant-env`

node_name         ENV['USER']
client_key       "#{current_dir}/client.pem"
validation_key   "#{current_dir}/chef-validator.pem"
chef_server_url  "https://chef.local"

cookbook_path     "#{current_dir}/../../cookbooks"
cookbook_email    `git config`

knife[:aws_access_key_id]       = ENV['AWS_ACCESS_KEY_ID']
knife[:aws_secret_access_key]   = ENV['AWS_SECRET_ACCESS_KEY']
knife[:ssh_user]                = ENV['SSH_USER'] || "ubuntu"

This approach also allows us to change configs arbitarily when running individual commands. Please see Github page for usage and other instructions.

Hope you will find the plugin useful. Looking forward to your comments and feedback on Hacker News.