The Vagrant driver is a new, experimental driver for spinning up a VagrantBox virtual machine, and installing Salt on it.
The Vagrant driver itself has no external dependencies.
The machine which will host the VagrantBox must be an already existing minion of the cloud server's Salt master. It must have Vagrant installed, and a Vagrant-compatible virtual machine engine, such as VirtualBox. (Note: The Vagrant driver does not depend on the salt-cloud VirtualBox driver in any way.)
[Caution: The version of Vagrant packaged for apt install
in Ubuntu 16.04 will not connect a bridged
network adapter correctly. Use a version downloaded directly from the web site.]
Include the Vagrant guest editions plugin:
vagrant plugin install vagrant-vbguest
.
Configuration of the client virtual machine (using VirtualBox, VMware, etc) will be done by Vagrant as specified in the Vagrantfile on the host machine.
Salt-cloud will push the commands to install and provision a salt minion on the virtual machine, so you need not (perhaps should not) provision salt in your Vagrantfile, in most cases.
If, however, your cloud master cannot open an SSH connection to the child VM,
you may need to let Vagrant provision the VM with Salt, and use some other
method (such as passing a pillar dictionary to the VM) to pass the master's
IP address to the VM. The VM can then attempt to reach the salt master in the
usual way for non-cloud minions. Specify the profile configuration argument
as deploy: False
to prevent the cloud master from trying.
# Note: This example is for /etc/salt/cloud.providers file or any file in
# the /etc/salt/cloud.providers.d/ directory.
my-vagrant-config:
minion:
master: 111.222.333.444
provider: vagrant
Because the Vagrant driver needs a place to store the mapping between the node name you use for Salt commands and the Vagrantfile which controls the VM, you must configure your salt minion as a Salt smb server. (See host provisioning example below.)
Vagrant requires a profile to be configured for each machine that needs Salt
installed. The initial profile can be set up at /etc/salt/cloud.profiles
or in the /etc/salt/cloud.profiles.d/
directory.
Each profile requires a vagrantfile
parameter. If the Vagrantfile has
definitions for multiple machines then you need a machine
parameter,
Salt-cloud uses SSH to provision the minion. There must be a routable path
from the cloud master to the VM. Usually, you will want to use
a bridged network adapter for SSH. The address may not be known until
DHCP assigns it. If ssh_host
is not defined, and target_network
is defined, the driver will attempt to read the address from the output
of an ifconfig
command. Lacking either setting,
the driver will try to use the value Vagrant returns as its ssh_host
,
which will work only if the cloud master is running somewhere on the same host.
The target_network
setting should be used
to identify the IP network your bridged adapter is expected to appear on.
Use CIDR notation, like target_network: '2001:DB8::/32'
or target_network: '192.0.2.0/24'
.
Profile configuration example:
# /etc/salt/cloud.profiles.d/vagrant.conf
vagrant-machine:
host: my-vhost # the Salt id of the virtual machine's host computer.
provider: my-vagrant-config
cwd: /srv/machines # the path to your Vagrantfile.
vagrant_runas: my-username # the username who defined the Vagrantbox on the host
# vagrant_up_timeout: 300 # (seconds) timeout for cmd.run of the "vagrant up" command
# vagrant_provider: '' # option for "vagrant up" like: "--provider vmware_fusion"
# ssh_host: None # "None" means try to find the routable IP address from "ifconfig"
# ssh_username: '' # also required when ssh_host is used.
# target_network: None # Expected CIDR address range of your bridged network
# force_minion_config: false # Set "true" to re-purpose an existing VM
The machine can now be created and configured with the following command:
salt-cloud -p vagrant-machine my-id
This will create the machine specified by the cloud profile
vagrant-machine
, and will give the machine the minion id of
my-id
. If the cloud master is also the salt-master, its Salt
key will automatically be accepted on the master.
Once a salt-minion has been successfully installed on the instance, connectivity to it can be verified with Salt:
salt my-id test.version
In order to query or control minions it created, each host minion needs to track the Salt node names associated with any guest virtual machines on it. It does that using a Salt sdb database.
The Salt sdb is not configured by default. The following example shows a simple installation.
This example assumes:
you are on a large network using the 10.x.x.x IP address space
your Salt master's Salt id is "bevymaster"
it will also be your salt-cloud controller
it is at hardware address 10.124.30.7
it is running a recent Debian family Linux (raspbian)
your workstation is a Salt minion of bevymaster
your workstation's minion id is "my_laptop"
VirtualBox has been installed on "my_laptop" (apt install is okay)
Vagrant was installed from vagrantup.com. (not the 16.04 Ubuntu apt)
"my_laptop" has done "vagrant plugin install vagrant-vbguest"
the VM you want to start is on "my_laptop" at "/home/my_username/Vagrantfile"
# file /etc/salt/minion.d/vagrant_sdb.conf on host computer "my_laptop"
# -- this sdb database is required by the Vagrant module --
vagrant_sdb_data: # The sdb database must have this name.
driver: sqlite3 # Let's use SQLite to store the data ...
database: /var/cache/salt/vagrant.sqlite # ... in this file ...
table: sdb # ... using this table name.
create_table: True # if not present
Remember to re-start your minion after changing its configuration files...
sudo systemctl restart salt-minion
# -*- mode: ruby -*-
# file /home/my_username/Vagrantfile on host computer "my_laptop"
BEVY = "bevy1"
DOMAIN = BEVY + ".test" # .test is an ICANN reserved non-public TLD
# must supply a list of names to avoid Vagrant asking for interactive input
def get_good_ifc() # try to find a working Ubuntu network adapter name
addr_infos = Socket.getifaddrs
addr_infos.each do |info|
a = info.addr
if a and a.ip? and not a.ip_address.start_with?("127.")
return info.name
end
end
return "eth0" # fall back to an old reliable name
end
Vagrant.configure(2) do |config|
config.ssh.forward_agent = true # so you can use git ssh://...
# add a bridged network interface. (try to detect name, then guess MacOS names, too)
interface_guesses = [get_good_ifc(), 'en0: Ethernet', 'en1: Wi-Fi (AirPort)']
config.vm.network "public_network", bridge: interface_guesses
if ARGV[0] == "up"
puts "Trying bridge network using interfaces: #{interface_guesses}"
end
config.vm.provision "shell", inline: "ip address", run: "always" # make user feel good
# . . . . . . . . . . . . Define machine QUAIL1 . . . . . . . . . . . . . .
config.vm.define "quail1", primary: true do |quail_config|
quail_config.vm.box = "boxesio/xenial64-standard" # a public VMware & Virtualbox box
quail_config.vm.hostname = "quail1." + DOMAIN # supply a name in our bevy
quail_config.vm.provider "virtualbox" do |v|
v.memory = 1024 # limit memory for the virtual box
v.cpus = 1
v.linked_clone = true # make a soft copy of the base Vagrant box
v.customize ["modifyvm", :id, "--natnet1", "192.168.128.0/24"] # do not use 10.x network for NAT
end
end
end
# file /etc/salt/cloud.profiles.d/my_vagrant_profiles.conf on bevymaster
q1:
host: my_laptop # the Salt id of your virtual machine host
machine: quail1 # a machine name in the Vagrantfile (if not primary)
vagrant_runas: my_username # owner of Vagrant box files on "my_laptop"
cwd: '/home/my_username' # the path (on "my_laptop") of the Vagrantfile
provider: my_vagrant_provider # name of entry in provider.conf file
target_network: '10.0.0.0/8' # VM external address will be somewhere here
# file /etc/salt/cloud.providers.d/vagrant_provider.conf on bevymaster
my_vagrant_provider:
driver: vagrant
minion:
master: 10.124.30.7 # the hard address of the master
Typing on the Salt master computer bevymaster
, tell it to create a new minion named v1
using profile q1
...
sudo salt-cloud -p q1 v1
sudo salt v1 network.ip_addrs
[ you get a list of IP addresses, including the bridged one ]
logged in to your laptop (or some other computer known to GitHub)...
[NOTE:] if you are using MacOS, you need to type
ssh-add -K
after each boot, unless you use one of the methods in this gist.
ssh -A vagrant@< the bridged network address >
# [ or, if you are at /home/my_username/ on my_laptop ]
vagrant ssh quail1
then typing on your new node "v1" (a.k.a. quail1.bevy1.test)...
password: vagrant
# [ stuff types out ... ]
ls -al /vagrant
# [ should be shared /home/my_username from my_laptop ]
# you can access other network facilities using the ssh authorization
# as recorded in your ~.ssh/ directory on my_laptop ...
sudo apt update
sudo apt install git
git clone ssh://git@github.com/yourID/your_project
# etc...