.. _getting-started-with-vagrant: ============================ Getting Started With Vagrant ============================ The Vagrant driver is a new, experimental driver for spinning up a VagrantBox virtual machine, and installing Salt on it. Dependencies ============ 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.) .. _Vagrant: https://www.vagrantup.com/ .. _VirtualBox: https://www.virtualbox.org/ \[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 ============= 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. .. code-block:: yaml # 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.) Profiles ======== 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, .. _`multiple machines`: https://www.vagrantup.com/docs/multi-machine/ 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: .. code-block:: yaml # /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: .. code-block:: bash 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: .. code-block:: bash salt my-id test.version .. _host provisioning example: Provisioning a Vagrant cloud host (example) =========================================== 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" .. code-block:: yaml # 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`` .. code-block:: ruby # -*- 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 .. code-block:: yaml # 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 .. code-block:: yaml # 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 Create and use your new Salt minion ----------------------------------- - Typing on the Salt master computer ``bevymaster``, tell it to create a new minion named ``v1`` using profile ``q1``... .. code-block:: bash 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`_. .. _this gist: https://github.com/jirsbek/SSH-keys-in-macOS-Sierra-keychain .. code-block:: bash 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)... .. code-block:: bash 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...