No commit activity in last 3 years
No release in over 3 years
Vagrant plugin to run custom Chef run list during provisioning
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.5
~> 10.0
~> 3.0
 Project Readme

Vagrant Lifecycle Plugin

Vagrant Lifecycle is a Vagrant plugin that allows execution of custom provisioning events for the Chef provisioners (Chef Solo, Chef Zero and Chef Client).

The primarily goal of this plugin is to ease the development and testing of Chef recipes intended for use on services like AWS OpsWorks.

Installation

  1. Install the latest version of Vagrant
  2. Install the Vagrant Lifecycle plugin:
$ vagrant plugin install vagrant-lifecycle

Usage

Example Vagrantfile configuration section for Vagrant Lifecycle:

Vagrant.configure("2") do |config|
  # Default lifecycle event. 
  # If set, the vagrant-lifecycle with alter the default vagrant provision run list.
  config.lifecycle.default_event = :setup

  # Lifecycle events configuration hash.
  # Each event needs a lambda with 2 parameters run_list and env and should return the new run list
  # Parameter env is vagrant-lifecycle plugin's middleware environment hash with various interesting keys:
  # * env[:ui] is an instance of ::Vagrant::UI::Interface
  # * env[:machine] is an instance of ::Vagrant::Machine etc.
  config.lifecycle.events = {
     :configure => lambda {|run_list, env|
       run_list + ["recipe[sample_cookbook::configure]"]
     },
     :deploy => lambda {|run_list, env|
       run_list + ["recipe[sample_cookbook::deploy]"]
     },
     :setup => lambda {|run_list, env|
       run_list + ["recipe[sample_cookbook::setup]"]
     }
  }
end

If you have configured the default_event, it will be run when you run provision the usual way:

$ vagrant provision

You can execute provisioning on the specific lifecycle event via command (for example for deploy event):

$ vagrant lifecycle -e deploy

Usage with other Vagrant plugins

Currently executed lifecycle event name is available in other Vagrant plugin's middlewares through :lifecycle_event key of the environment hash. Please note that this key will not be set during regular provision even if the lifecycle.default_event is configured.

More examples

Evaluate run list based on lifecycle event and node roles

Example Vagrantfile configuration section:

# Required for $LAST_MATCH_INFO used bellow
require "English"

Vagrant.configure("2") do |config|
  config.lifecycle.events = {
     :configure => lambda {|run_list, env|
       run_list.flat_map {|r|
         case r
         when /^role\[(?<role>.*)\]/
           %W(role[#{$LAST_MATCH_INFO['role']}] recipe[layer_#{$LAST_MATCH_INFO['role']}::configure])
         else
           [r]
         end
       }
     },
     :deploy => lambda {|run_list, env|
       run_list.flat_map {|r|
         case r
         when /^role\[(?<role>.*)\]/
           %W(role[#{$LAST_MATCH_INFO['role']}] recipe[layer_#{$LAST_MATCH_INFO['role']}::configure] recipe[layer_#{$LAST_MATCH_INFO['role']}::deploy])
         else
           [r]
         end
       }
     },
     :setup => lambda {|run_list, env|
       run_list.flat_map {|r|
         case r
         when /^role\[(?<role>.*)\]/
           %W(role[#{$LAST_MATCH_INFO['role']}] recipe[layer_#{$LAST_MATCH_INFO['role']}::setup])
         else
           [r]
         end
       }
     }
  }
end

Require additional parameter(s) for a specific lifecycle event

Example Vagrantfile configuration section:

# Required for $LAST_MATCH_INFO used bellow
require "English"

Vagrant.configure("2") do |config|
  config.lifecycle.events = {
    :deploy => lambda {|run_list, env|
      options = {}
      opt_parser = OptionParser.new do |parser|
        parser.on("-a", "--application APPLICATION", "Application to deploy") do |p|
          options[:application] = p
        end
        parser.parse!
      end
      opt_parser.program_name="vagrant lifecycle -e deploy"

      if options.empty?
        puts opt_parser.help
        exit 1
      end

      unless options.key?(:application)
        env[:ui].error "Application parameter missing!"
        exit 1
      end

      run_list.flat_map {|r|
        case r
        when /^role\[(?<role>.*)\]/
          %W(role[#{$LAST_MATCH_INFO['role']}] recipe[layer_#{$LAST_MATCH_INFO['role']}::configure] recipe[layer_#{$LAST_MATCH_INFO['role']}::deploy_#{options[:application]}])
        else
          [r]
        end
      }
    }        
  }
end

Sample usage:

$ vagrant lifecycle -e deploy -a really_cool_app

Use specific machine info

Example Vagrantfile configuration section:

Vagrant.configure("2") do |config|
  config.lifecycle.events = {
     :configure => lambda {|run_list, env|
       run_list + ["recipe[sample_cookbook::configure]"]
     },
     :deploy => lambda {|run_list, env|
       if env[:machine].name.to_s == "node1"
         run_list + ["recipe[sample_cookbook::deploy]"]
       else
         run_list
       end
     },
     :setup => lambda {|run_list, env|
       run_list + ["recipe[sample_cookbook::setup]"]
     }
  }
end

Simulate OpsWorks stack

Both vagrant-lifecycle and vagrant-databags plugins are required for this example. Sample code is available in the vagrant-databags documentation.