-
-
Save bnortman/99be49d47a3e372db1864d1a57365714 to your computer and use it in GitHub Desktop.
Create a vagrant box with chef server provisioning and automatic client and node cleanup on the server when the vagrant box gets destroyed. All necessary api keys and config options are taken from environment variables. The knife.rb must live inside a .chef directory besides the Vagrantfile.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Opscode chef configurations. | |
export KNIFE_CHEF_SERVER="https://chef-api.example.com" | |
export KNIFE_CLIENT_KEY="$HOME/.chef/client.pem" | |
export KNIFE_NODE_NAME="myclient" | |
export KNIFE_VALIDATION_CLIENT_NAME="chef-validator" | |
export KNIFE_VALIDATION_CLIENT_KEY="$HOME/.chef/chef-validator.pem" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Logging. | |
log_level :debug | |
log_location STDOUT | |
# Chef server configuration. | |
chef_server_url "#{ENV['KNIFE_CHEF_SERVER']}" | |
client_key "#{ENV['KNIFE_CLIENT_KEY']}" | |
node_name "#{ENV['KNIFE_NODE_NAME']}" | |
validation_client_name "#{ENV['KNIFE_VALIDATION_CLIENT_NAME']}" | |
validation_key "#{ENV['KNIFE_VALIDATION_CLIENT_KEY']}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- mode: ruby -*- | |
# vi: set ft=ruby : | |
require 'chef' | |
Chef::Config.from_file(File.join(File.dirname(__FILE__), '.chef', 'knife.rb')) | |
vms = { | |
"testbox" => { | |
:box => "precise64", | |
:ipaddress => "192.168.33.10", | |
:run_list => "role[base]" | |
} | |
} | |
Vagrant::Config.run do |global_config| | |
vms.each_pair do |name, options| | |
global_config.vm.define name do |config| | |
# Every Vagrant virtual environment requires a box to build off of. | |
config.vm.box = options[:box] | |
vm_name = "vagrant-#{name}-#{ENV['USER']}" | |
# Boot with a GUI so you can see the screen. (Default is headless) | |
# config.vm.boot_mode = :gui | |
# Assign this VM to a host-only network IP, allowing you to access it | |
# via the IP. Host-only networks can talk to the host machine as well as | |
# any other machines on the same network, but cannot be accessed (through this | |
# network interface) by any external networks. | |
config.vm.network :hostonly, options[:ipaddress] | |
config.vm.host_name = vm_name | |
# Enable provisioning with chef server, specifying the chef server URL, | |
# and the path to the validation key (relative to this Vagrantfile). | |
config.vm.provision :chef_client do |chef| | |
chef.chef_server_url = Chef::Config[:chef_server_url] | |
chef.log_level = Chef::Config[:log_level] | |
chef.node_name = vm_name | |
chef.validation_key_path = Chef::Config[:validation_key] | |
chef.validation_client_name = Chef::Config[:validation_client_name] | |
chef.environment = "development" | |
run_list = [] | |
run_list << ENV['CHEF_RUN_LIST'].split(",") if ENV.has_key?('CHEF_RUN_LIST') | |
chef.run_list = [options[:run_list].split(","), run_list].flatten | |
end | |
end | |
end | |
end | |
module Vagrant | |
module Provisioners | |
class Base | |
require 'chef' | |
require 'chef/config' | |
require 'chef/knife' | |
end | |
class ChefClient | |
::Chef::Config.from_file(File.join(File.dirname(__FILE__), '.chef', 'knife.rb')) | |
def cleanup | |
node = env[:vm].config.vm.host_name | |
env[:ui].info "Attempting to clean up client '#{node}' on chef server." | |
begin | |
::Chef::REST.new(::Chef::Config[:chef_server_url]).delete_rest("clients/#{node}") | |
rescue Net::HTTPServerException => e | |
if e.message == '404 "Not Found"' | |
env[:ui].info "Client '#{node}' not found." | |
else | |
env[:ui].error "An error occured. You will have to remove the client manually." | |
end | |
rescue Exception => e | |
env[:ui].error "An error occured. You will have to remove the client manually." | |
else | |
env[:ui].info "Client '#{node}' successfully removed from chef server." | |
end | |
env[:ui].info "Attempting to clean up node '#{node}' on chef server." | |
begin | |
::Chef::REST.new(::Chef::Config[:chef_server_url]).delete_rest("nodes/#{node}") | |
rescue Net::HTTPServerException => e | |
if e.message == '404 "Not Found"' | |
env[:ui].info "Node '#{node}' not found." | |
else | |
env[:ui].error "An error occured. You will have to remove the node manually." | |
end | |
rescue Exception => e | |
env[:ui].error "An error occured. You will have to remove the node manually." | |
else | |
env[:ui].info "Node '#{node}' successfully removed from chef server." | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment