Setup for a SaltStack Vagrant Environment

Often when writing Salt related code, I need an environment in which ideas can quicly be tested and interated upon. I have found that Vagrant is usually suited perfectly for filling this need. If you want to use Vagrant as well, first you’ll need to install it from the VagrantUp Hashicorp website.

The idea here is to create an environment with a single master and minion from which changes to Salt formulas, modules, pillars, orchs, beacons, engines, etc. can quickly and easily be tested.

Setting Up Vagrant

Inside this directory, I need a few files:

  • Vagrantfile
  • The salt bootstrap script aka bootstrap-salt.sh
  • A salt-master config file aka salt_master_config
  • A salt-minion config file aka salt_minion_config
  • A YAML file to describe the hosts to be created aka vagrant_hosts.yml

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :


require 'yaml'
hosts = YAML.load_file('vagrant_hosts.yml')


# Set options for the network interface configuration. All values are
# optional, and can include:
# - ip (default = DHCP)
# - netmask (default value = 255.255.255.0
# - mac
# - auto_config (if false, Vagrant will not configure this network interface
# - intnet (if true, an internal network adapter will be created instead of a
# host-only adapter)
def network_options(host)
options = {}
if host.has_key?('ip')
options[:ip] = host['ip']
options[:netmask] = host['netmask'] ||= '255.255.255.0'
else
options[:type] = 'dhcp'
end


if host.has_key?('mac')
options[:mac] = host['mac'].gsub(/[-:]/, '')
end
if host.has_key?('auto_config')
options[:auto_config] = host['auto_config']
end
if host.has_key?('intnet') && host['intnet']
options[:virtualbox__intnet] = true
end
options
end


def box_choice(host)
choice = ''
if host.has_key?('box')
choice = host['box']
else
choice = 'centos/7'
end
choice
end


$script = <<-SCRIPT
sudo yum -y install python3
sudo ln -s /srv/salt /etc/salt
SCRIPT


Vagrant.configure("2") do |config|
hosts.each do | host |
if host.has_key?('sync_folder')
config.vm.synced_folder host['sync_folder']['host'], host['sync_folder']['guest'], type: 'nfs'
end
config.vm.define host['name'] do | node |
node.vm.box = box_choice(host)
node.vm.hostname = host['name']
node.vm.network :private_network, network_options(host)
node.vm.provider :virtualbox do | vb |
vb.name = host['name']
vb.cpus = host['cpus'] ||= 1
vb.memory = host['memory'] ||= 512
end


if host.has_key?('sync_folder')
node.vm.provision 'shell',
inline: $script
end


node.vm.provision :salt do | salt |
if host.has_key?('sync_folder')
salt.install_master
salt.no_minion
salt.master_config = 'salt_master_config'
salt.bootstrap_script = 'bootstrap-salt.sh'
salt.bootstrap_options = '-M'
salt.python_version = '3'
else
salt.minion_config = 'salt_minion_config'
salt.run_highstate = false
salt.bootstrap_script = 'bootstrap-salt.sh'
end
salt.install_type = 'stable'
salt.install_args = '2019.2'
end
end
end
end

Salt-Bootstrap Script

curl -o bootstrap-salt.sh -L https://bootstrap.saltstack.com

Salt-Master Config

grep -v '^$\|^#' master > salt_master_config

Salt-Minion Config

master: 172.28.128.10 
file_client: remote
hash_type: sha512

Vagrant Hosts YAML

- name: minion1
cpu: 1
memory: 1024
box: centos/7
- name: master1
cpu: 1
memory: 1024
box: centos/7
ip: 172.28.128.10
sync_folder:
host: "~/Documents/salt-master-configuration"
guest: "/srv/salt"

The magic in this setup is:

  1. The master uses an NFS mount to the host for the Salt pillars, states, etc.
  2. Using the name key in the Vagrant Hosts YAML, we can simulate any environment.
  3. We can run a different version of Salt just by modifying the Vagrantfile.
  4. Minions come up automatically pointed to the Master. Their keys still must be approved manually, but that’s a small price to pay. Don’t forget, the salt pki is on your host, so you’re adding a minion key there.

Caveat

Using Vagrant

Typically, while I’m using this set up, I have an editor with the Salt related code I’m working on open as well as a terminal window with an SSH connection to minion1 running in Vagrant. Because Vagrant has setup an NFS mount between the salt-master-configuration directory on my laptop and the master1 instance, as I make changes in the file in the editor, I can use salt-call on the minion to check the effect.

Originally published at https://smartaleksolutions.com on September 8, 2020.

Climber, surfer, yogi, dad who does some IT on the side to get by.

Climber, surfer, yogi, dad who does some IT on the side to get by.