Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
420 lines (261 sloc) 10.1 KB


Donate via flattr Donate via Gratipay Apache-2.0-licensed Join Gitter Chat Join Internet Relay Chat

A Vagrant VM that uses SaltStack to setup a SaltStack sandbox for SaltStack demonstration


You need:

  • basic vagrant knowledge (RTFM skills are sufficient)
  • Vagrant >= 1.6.5 ($ vagrant -v)
  • VirtualBox >= 3


Preparing Vagrant VM(s)

Preparing the setup:

$ git clone --recursive saltbox
$ cd saltbox/
$ cp nodes.yaml.dist nodes.yaml
$ cd vagrant/
$ vagrant up master1
$ vagrant ssh master1
$ sudo -i

Hint: To continue with full awesomeness, setup ZSH shell (see Misc section).

Installing Salt manually

Hint: This is not needed when you haven't disabled saltstack_install_bootstrap in the file nodes.yaml.

# /vagrant/scripts/custom/saltstack_install_bootstrap/
# /vagrant/scripts/custom/saltstack_config/
# /vagrant/scripts/custom/saltstack_services/


Check Salt is installed:

# salt-call test.version

Check Salt minion/ master configuration:

# less /etc/salt/minion
# less /etc/salt/master
# tree -l /srv/salt/

Module Documentation

Read the docs:

# salt-call sys.doc
# salt-call sys.doc pillar
# salt-call sys.doc pillar.get

Job Managment

Add recurring jobs (like cronjobs) ad-hoc using the minion job scheduler:

# salt-call schedule.add test_ping function='' seconds=15
# salt-call schedule.add apply_states function='disk.usage' minutes=30
# salt-call schedule.list

Manage arbitrary cron jobs:

# crontab -e
# salt-call root

Software Package Management

# salt-call pkg.install rubygems
# salt-call gem.install lolcat
# salt-call pkg.list_upgrades | lolcat

Grains data

See list of grains:

# salt-call grains.items
# salt-call grains.get os
# salt-call grains.get os --out=json
# salt-call grains.get os --out=yaml

Get minion OS statistics (requires a Salt master):

# salt '*' grains.get os --out=yaml | cut -f2 -d' ' | sort | uniq -c | sort -nr

Pillar data

See specific pillar data:

# salt-call pillar.get users
# salt-call pillar.get users --out=json

System User/Group management

# salt-call user.list_users
# salt-call user.delete operator
# salt-call operator
# salt-call user.add operator
# salt-call operator

Installing and Running a Webserver

# salt-call pkg.install httpd
# salt-call pkg.version httpd
# salt-call apache.modules
# salt-call service.restart httpd
# salt-call 'curl -vs'
# salt-call 'echo This is a test page > /var/www/html/index.html'
# salt-call 'curl -vs'

Retreiving remote files

# salt-call cp.get_url /tmp/index.html
# salt-call 'head -20 /tmp/index.html'

Applying Salt States for software & configuration mgmt

Installing Apache httpd, deploying a httpd.conf template and restart the service afterwards:

# salt-call -l debug state.sls saltbox.simple_apache_httpd test=True
# salt-call -l debug state.sls saltbox.simple_apache_httpd
# echo unwantend content >> /etc/httpd/conf/httpd.conf
# salt-call -l debug state.sls saltbox.simple_apache_httpd

Doing the same as before but now making use of the Salt pillar system:

# head /srv/salt/pillar/shared/common.sls
# salt-call -l debug pillar.get httpd
# salt-call -l debug pillar.get httpd --out=json
# diff -u /srv/salt/states/saltbox/simple_apache_httpd/init.sls /srv/salt/states/saltbox/simple_apache_httpd_dynamic/init.sls
# tail /srv/salt/contrib/states/saltbox/files/httpd_dynamic.conf
# salt-call -l debug state.sls saltbox.simple_apache_httpd_dynamic test=True
# salt-call -l debug state.sls saltbox.simple_apache_httpd_dynamic
# curl -vs

Feel free to play around with Salt by modifying the files that you've found in /srv/salt/ for hacking.

Adding custom Salt States

To develop and test self-written Salt pillar or state files simply store them in /srv/salt/pillar/shared/ (Pillar) and /srv/salt/states/ (States). The default minion/master configuration looks for pillar (pillar_roots) and state (file_roots) files within these folders.

Working with the master

Minion key management:

# salt-key
# head /etc/salt/autosign.conf
# salt-key -h

Targeting (specifying minions to execute commands):

# salt -v '' test.version
# salt -v 'master1*' test.version
# salt -v -C 'G@os_family:RedHat' test.version
# salt -v -C 'G@os_family:RedHat and I@role:webserver' test.version
# salt -v -C '*' pillar.get role
# salt -v -C '*' test.version

Executing some execution modules:

# salt -v 'master1*' state.sls saltbox.simple_apache_httpd_dynamic test=True
# salt -v 'master1*' pkg.install openssl refresh=True
# salt -v 'master1*' pkg.list_upgrades
# salt -v 'master1*' service.get_all
# salt -v 'master1*' service.restart httpd
# salt -v 'master1*' disk.usage
# salt -v 'master1*' git.clone /tmp/github.clone git://; ls -al /tmp/github.clone/
# salt -v 'master1*' grains.get os_family

Targeting minions based on hostnames, grains and more (requires some more minions):

# salt -C 'E@minion[13-37]+'
# salt -L 'minion42,master1,minion69'
# salt -C 'G@os:CentOS'
# salt -C 'G@os:Debian'
# salt -C 'G@os:Arch'
# salt -C 'S@ and P@os:CentOS'
# salt -C 'S@ and P@os:CentOS'

Multi-Node Setup and Salt Reactor (Advanced Topic)

The following steps are also explained in a blog article on my blog.

$ cd saltbox/

Enable minion1 in nodes.yaml:

$ vim nodes.yaml

Configure Salt Master (incl. Reactor) based on Pillar data:

$ cd vagrant/
$ vagrant up master1
$ vagrant ssh master1
$ sudo -i
# salt-call state.highstate
# less /etc/salt/master
# tree -l /srv/salt/contrib/reactor/salt/files
# less /srv/salt/states/saltbox/reactor_apache_httpd/init.sls
# salt-call
# tail -f /tmp/salt.reactor.log

Start an additional terminal and start new VMs acting as arbitrary minions:

$ cd saltbox/vagrant
$ vagrant up minion1
$ vagrant ssh minion1
$ sudo -i
# service salt-minion restart

Now wait for log entries in /tmp/salt.reactor.log.

Salt Cloud VM Deployment

This doesn't work out of the box since you need provider API credentials to deploy cloud VMs.

Prepare the system for Salt Cloud:

# Required states:
# salt-call -ldebug state.sls,repos,git,tools

# With optional states:
# salt-call -ldebug state.sls,repos,git,tools,zsh,users,vim

Add - private in /srv/salt/pillar/shared/top.sls to include the Pillar file /srv/salt/pillar/shared/private.sls with the following contents:

      apikey: YourLinodeAPIKey

Now Linode API access should be possible.

List available DC locations of the provider defined in provider config linode01:

# salt-cloud --list-locations=linode01

List available VM images of the provider defined in provider config linode01:

# salt-cloud --list-images=linode01

Deploy a VM using the profile linode_2048_centos_fra and name it minion1:

# salt-cloud -l debug -p linode_2048_centos_fra vm1

Deploy even more VMs:

# salt-cloud --map /vagrant/shared/misc/salt-cloud/map1.yaml --parallel --hard

Destroy them all:

# salt-cloud --map /vagrant/shared/misc/salt-cloud/map1.yaml --parallel --destroy --assume-yes


Setup ZSH profile:

# salt-call -l debug state.sls git,tools,zsh test=False
# exit
$ sudo -i

Saltbox/Vagrant Maintenance

Update saltbox-vagrant VM(s)/ Git submodules as follows:

# cd saltbox/
# git pull
# git submodule update --init --recursive .

Additional resources

Please see for some more bits of information about the vagrant VM.

Alternative bootstrap arguments: -M -K -g git 2014.7