Provision Vagrant boxes using Saltstack.
Discussion and questions happen in #salt
on Freenode IRC. ping akoumjian
.
Just like Chef or Puppet, Salt can be used as a provisioning tool. Salty Vagrant lets you use your salt state tree and a your minion config file to automatically build your dev environment the same way you use salt to deploy for other environments.
There are two different ways to use Salty Vagrant. The simplest way uses the salt minion in a masterless configuration. With this option you distribute your state tree along with your Vagrantfile and a dev minion config. The minion will bootstrap itself and apply all necessary states.
The second method lets you specify a remote salt master, which assures that the vagrant minion will always be able to fetch your most up to date state tree. If you use a salt master, you will either need to manually accept new vagrant minions on the master, or distribute preseeded keys along with your vagrant files.
- Install Vagrant
- Install Salty Vagrant (
vagrant gem install vagrant-salt
) - Get the Ubuntu 12.04 base box:
vagrant box add precise64 http://files.vagrantup.com/precise64.box
- Create/Update your
Vagrantfile
(Detailed in Configuration) - Place your salt state tree in
salt/roots/salt
- Place your minion config in
salt/minion
[1] - Run
vagrant up
and you should be good to go.
[1] | Make sure your minion config sets file_client: local for masterless |
If you are already using Salt for deployment, you can use your existing master to provision your vagrant boxes as well. You will need to do one of the following:
- Manually accept the vagrant's minion key after it boots. [2]
- Preseed the Vagrant box with minion keys pre-generated on the master
[2] | This is not recommended. If your developers need to destroy and rebuild their VM, you will have to repeat the process. |
On the master, create the keypair and add the public key to the accepted minions folder:
root@saltmaster# salt-key --gen-keys=[minion_id] root@saltmaster# cp minion_id.pub /etc/salt/pki/minions/[minion_id]
Replace [minion_id]
with the id you would like to assign the minion.
Next you want to bundle the key pair along with your Vagrantfile, the salt_provisioner.rb, and your minion config. The directory should look something like this:
myvagrant/ Vagrantfile salt/ minion.conf key/ minion.pem minion.pub
You will need to determine your own secure method of transferring this package. Leaking the minion's private key poses a security risk to your salt network.
The are two required settings for your minion.conf
file:
master: [master_fqdn] id: [minion_id]
Make sure you use the same [minion_id]
that you used on the master or
it will not match with the key.
Create/Update your Vagrantfile
per the example provided in the Configuration section.
Finally, you should be able to run vagrant up
and the salt should put your
vagrant minion in state.highstate.
Your Vagrantfile
should look roughly like this:
Vagrant::Config.run do |config| config.vm.box = "precise64" ## Use all the defaults: config.vm.provision :salt do |salt| salt.run_highstate = true ## Optional Settings: # salt.minion_config = "salt/minion.conf" # salt.salt_install_type = "git" # salt.salt_install_args = "develop" ## Only Use these with a masterless setup to ## load your state tree: # salt.salt_file_root_path = "salt/roots/salt" # salt.salt_pillar_root_path = "salt/roots/pillar" ## If you have a remote master setup, you can add ## your preseeded minion key # salt.master = true # salt.minion_key = "salt/key/testing.pem" # salt.minion_pub = "salt/key/testing.pub" end end
Inside of your Vagrantfile, there are a few parameters you can assign depending on whether you are running masterless or with a remote master.
- minion_config : "salt/minion.conf"
- Path to your minion configuration file.
- minion_key : false
- String path to your minion key. Only useful with
master=true
- minion_pub : false
- String path to your minion public key. Only useful with
master=true
- master : false
- Boolean whether or not you want to use a remote master. If set to false,
make sure your minion config file has
file_client: local
set. - salt_install_type : "stable" : "daily" : "git"
- Whether to install from a distribution's stable package manager, a daily ppa, or git treeish.
- salt_install_args : ""
- When performing a git install, you can specify a branch, tag, or any treeish.
- salt_file_root_path : "salt/roots/salt"
- String path to your salt state tree. Only useful with
master=false
. - salt_file_root_guest_path : "/srv/salt"
- Path to share the file root state tree on the VM. Only use with
master=false
. - salt_pillar_root_path : "salt/roots/pillar"
- Path to share your pillar tree. Only useful with
master=false
. - salt_pillar_root_guest_path : "/srv/pillar"
- Path on VM where pillar tree will be shared. Only use with
master=true
- salt_nfs_shared_folders: true or false
- Some vagrant machines do not support shared folders, for example, FreeBSD. So, if you're running salty vagrant using a masterless setup, using an NFS share might be your only option. This option tries to make salty work with NFS. For more info, please check the Vagrant documentation regarding NFS Shares.
Before Salt can be used for provisioning on the target virtual box, the
binaries need to be installed. Since Vagrant and Salt support many
different distributions and versions of operating systems, the Salt
installation process is handled by the shell script
scripts/bootstrap-salt-minion.sh
. This script runs through a series of
checks to determine operating system type and version to then install the
Salt binaries using the appropriate methods.
In order to install salt for a distribution you need to define:
- To Install Dependencies, which is required, one of:
- install_<distro>_<distro_version>_<install_type>_deps
- install_<distro>_<distro_version>_deps
- install_<distro>_<install_type>_deps
- install_<distro>_deps
- To install salt, which, of course, is required, one of:
- install_<distro>_<distro_version>_<install_type>
- install_<distro>_<install_type>
- And optionally, define a post install function, one of:
- install_<distro>_<distro_versions>_<install_type>_post
- install_<distro>_<distro_versions>_post
- install_<distro>_<install_type>_post
- install_<distro>_post
Below is an example for Ubuntu Oneiric:
- install_ubuntu_1110_deps() {
- apt-get update apt-get -y install python-software-properties add-apt-repository -y 'deb http://us.archive.ubuntu.com/ubuntu/ oneiric universe' add-apt-repository -y ppa:saltstack/salt
}
- install_ubuntu_1110_post() {
- add-apt-repository -y --remove 'deb http://us.archive.ubuntu.com/ubuntu/ oneiric universe'
}
- install_ubuntu_stable() {
- apt-get -y install salt-minion
}
Since there is no install_ubuntu_1110_stable()
it defaults to the
unspecified version script.
The bootstrapping script must be plain POSIX sh only, not bash or another shell script. By design the targeting for each operating system and version is very specific. Assumptions of supported versions or variants should not be made, to avoid failed or broken installations.
- Ubuntu 10.x/11.x/12.x
- Debian 6.x
- CentOS 6.3
Users have reported that vagrant plugins do not work with the debian packaged vagrant (such as Ubuntu repository). Installing vagrant with gem should work.
sudo apt-get remove vagrant
sudo gem install vagrant
vagrant gem install vagrant-salt
That should get you up and running.
wget https://github.com/saltstack/salty-vagrant/tarball/master -O salty-vagrant.tar.gz
tar zxf salty-vagrant.tar.gz
cd saltstack-salty-vagrant-[hash]
gem build vagrant-salt.gemspec
vagrant gem install vagrant-salt-[version].gem