Testing SaltStack with Vagrant

Recently updated on

We use SaltStack as our primary configuration management tool for server provisioning and management.  I’ve been doing a fair amount of updates to this process and have primarily been using Vagrant to test my updates locally before pushing out to our Salt Master. 

I am going to assume you already have your Salt project set up with your states, pillars, etc.  If you want to learn about SaltStack itself, you should go check out the official walkthrough.  I also assume you have Vagrant installed and configured. If you want to learn more about Vagrant, you should checkout the documentation.

Vagrant has a built-in Salt provisioner that you can use to provision your Vagrant box.  Vagrant will automatically check for and execute the provision section when the machine is booted for the first time or when you run “vagrant provision.”  It is especially useful that we can run “vagrant provision” without the need to recreate the Vagrant box so that we can quickly iterate and view changes.

The first thing we need to do is add our Salt project as a synced directory so our Salt States checked out on our Vagrant host are visible to our Vagrant guest machine.  So we need to add the following line to our Vagrantfile:

config.vm.synced_folder "/srv/sls/", "/srv/"

I happen to have my Salt checkout at /srv/sls/, but you can replace this with wherever you store your Salt project.  Additionally, depending on how you have your Salt project set up, you may link to /srv/salt/ instead of /srv/.  We need to have this folder synced so that we can run the Salt minion on our Vagrant machine without needing a Salt Master.

Next we need to add the provision section to our Vagrantfile:

config.vm.provision :salt do |salt|
  salt.pillar({"is_vagrant" => true})
  salt.minion_config  = "salt/minion"
  salt.run_highstate = true

The important lines for this config are salt.minion_config and salt.run_highstate.  Salt.run_highstate tells the provisioner that we want to run the state.highstate whenever provisioning happens.  Salt.minion_config option refers to another file we will need to create to store specific information about the minion we are using, so that when Salt runs on our Vagrant machine it has all the information it needs.  We will talk more about the minion config file later.  

Salt.pillar is particularly powerful.  Using it you can specify pillar data for your Salt States to use.  In my instance, there are some particular things that I want to do if I’m provisioning onto a Vagrant machine, mostly to ensure that my Vagrant user has the correct permissions and is a member of the correct groups.

Salt.minion_config is another file we will need to create.  Note that this is a relative path to the location of the config file, so if it doesn’t exist we will need to create a Salt folder in the directory that contains the Vagrantfile and create a file named minion inside of it.  Let’s look at a minion file:

master: localhost
file_client: local
  client: acme
  servertype: webserver     

It is important that we say where the Salt Master is located. We will never change this from localhost during our testing.  File_client: local tells Salt that we are running in a masterless setup.  Grains is where we can specify the same information we normally would for a server in its minion config.  We have specific things that need to happen depending on the client, so we need to specify the client.

A full gist of both the Vagrantfile and minion config can be found here.

A full listing of installation and provisioning options for SaltStack on Vagrant can be found here.

Share Twitter, LinkedIn, Facebook

Hey there...
Would you mind sharing this post? We would greatly appreciate it.
Thank you.