Oh-My-Vagrant by James
- Overview
- Project description - What the project does
- Setup - Getting started with Oh-My-Vagrant
- Usage/FAQ - Notes on usage and frequently asked questions
- Reference - Detailed reference
- Examples - Example configurations
- Limitations - Vagrant versions, OS compatibility, etc...
- Development - Background on module development and reporting bugs
- Authors - Authors and contact information
The Oh-My-Vagrant project lets you describe your Vagrant configuration declaratively in YAML, and provides a general purpose Vagrantfile that reads that configuration and passes it to Vagrant.
Vagrant is great, but it has some rough edges, especially if you want your Vagrant files to work across multiple local virt providers (e.g. VirtualBox, libvirt), and multiple host operating systems (whether Windows, Mac OS X, or your preferred flavour of Linux).
The Oh-My-Vagrant project provides a rich Vagrantfile that avoids (or works around) many of those rough edges by reading in the desired configuration from a declarative YAML syntax that allows for dynamic lists of virtual machines, Puppet(/Ansible/Chef/Salt) integration, docker containers in each machine, automatic DNS setup, easy box downloading, and more!
Instead of having to write complex, partially declarative pseudo-ruby code to
create and modify a Vagrant environment, you can instead do all the manipulation
simply by editing a short omv.yaml
definition file. The provided Vagrantfile
then reads this definition to dynamically configure Vagrant. Additionally, it
integrates with code to help you run existing configuration management utilities,
kick off docker commands, and more!
For more information, start by reading and working through the introductory blog post.
Oh-My-Vagrant is designed to be able to deal with:
- Dynamic lists of named virtual machines
- Dynamic lists of numbered virtual machines
- Automatic Puppet/Ansible/Chef/Salt integration
- Automatic DNS setup
- Easy Vagrant box downloading (for certain OS choices)
- Docker container enablement in each virtual machine
- Automatic Kubernetes setup
- And much more...
Oh-My-Vagrant now supports a "mainstream" mode. This is the most common way to
use OMV when it is installed via your package manager. You interact with it
entirely with the omv
binary. The omv
binary works exactly like the
vagrant
command that you're used to, except that it works directly on the
omv.yaml
file, and hides the Vagrantfile complexity inside a system folder.
To initialize a new OMV environment, you can run:
$ omv init
to automatically create an omv.yaml
file. If you supply a path as an argument
to the init verb, then all OMV project specific files will be stored in this
sub directory, to avoid cluttering up your project root directory.
For most use cases, the simple usage of Oh-My-Vagrant should fulfill all your needs. Start by recursively cloning the project, and entering the vagrant/ directory:
$ git clone --recursive https://github.com/purpleidea/oh-my-vagrant
$ cd oh-my-vagrant/vagrant/
In this directory (or any of the children directories), you can run typical vagrant command line tools, which will use the powerful Vagrantfile provided. Instead of changing the pseudo-ruby code used in the Vagrantfile, you can instead customize the behaviour by modifying a simple omv.yaml file.
Everytime you run a vagrant command, the omv.yaml file will be read in (if it exists) parsed, and then written out in the same location. As a result, any erroneous, not compliant, or non parseable data you put in this file will be lost.
If you do not have a omv.yaml template, running the vagrant status
command will cause one to be generated. Play around with the settings in the
omv.yaml file, and forget about the days where small changes to your
environment, required pasting in a mess of code.
The complex use case allows Oh-My-Vagrant to be used as a platform that you can build a "module" on top of. This module can provide a homework environment, a set of interactive classwork lessons, the definitions for a demonstration cluster, and perhaps much more.
Steps for writing a custom module is currently undocumented. Please help improve this documentation by submitting a patch! In the meantime, you can refer to one of the existing Oh-My-Vagrant modules, if you're comfortable learning by example. It's fairly straightforward, but here are some quick pointers:
- Your module should be a separate git repo with the correct format.
- You'll need to set the omv.yaml "folder" parameter to match the name of your module.
- Include your module folder as a git submodule, in the directory next to the omv.yaml file provided with the Oh-My-Vagrant project. You should name your branch module/your_module_name. You should keep a reference to the branch with your module in it in this manner, and rebase your branch against the newer git master branch as often as you can.
- It's fairly straightforward once you look at an example. If you're stuck, your author would be happy to help out in exchange for code or documentation patches.
Example modules should be added as git submodules in a branch named: module/your_module_name. For example, if your module is called gluster, then you should create a branch named: module/gluster. If you're looking for an example module, so that you can ascertain the format, and learn what is possible, here is a list of examples:
(Send your questions as a patch to this FAQ! I'll review it, merge it, and respond by commit with the answer.)
I wasted enough time making custom Vagrant environments for more than one project. I took what I learnt about Vagrant, and generalized that in a single project. Now I don't have to duplicate code, or waste time when I want to make changes to my Vagrant environment.
Each VM brought up by OMV and vagrant-libvirt typically has two interfaces by
default. The first interface on the VM (which uses DHCP) is used to initially
get a connection to vagrant, since vagrant finds the machines by looking in the
DHCP leases table in Dnsmasq. This is the only way vagrant can find the IP
address. It would be great if there was an out of band communication method,
but nothing like this exists in vagrant-libvirt at this time. After vagrant
has found the VM, it makes all of its changes over this interface using SSH.
Since the first interface requires DHCP, and because many multi host clusters
prefer a consistent (statically assigned) IP address across reboots, OMV adds a
second interface which has this statically assigned address. It also provides
DNS for this network interface via the /etc/hosts
file.
Every VM created by OMV includes an extra entry in the /etc/hosts
file:
[vagrant@omv1 ~]$ cat /etc/hosts
...
## vagrant-hostmanager-start
192.168.123.100 omv1.example.com omv1
192.168.123.3 omv.example.com omv
## vagrant-hostmanager-end
...
The 192.168.123.3 omv.example.com omv
line represents a virtual
IP address reserved on every VM in the cluster. It's unused by default and can
be used by the developer for any purpose. It's commonly used by keepalived when
using the VM cluster to demonstrate leader election.
I've written a bunch about Vagrant and Vagrant-Libvirt on my technical blog. Since things have changed over the years, more recent articles are probably more relevant, and there may be old information which is no longer necessary. As a result, use your judgement, and in doubt, feel free to ask. In particular, there are a few articles which are probably still relevant, and which will be very useful. They are:
Yes, absolutely. This provides puppet integration, but it is entirely optional. If you'd like to add integration for another configuration management system, please send a patch.
This project has some useful dependencies which are included in the main
project as git submodules. To ensure you get all of the code, make sure you do
an initial clone with the --recursive
flag. Example:
git clone --recursive https://github.com/purpleidea/oh-my-vagrant/
Almost all of the code is vagrant
specific ruby code, therefore OMV should
work on anything that vagrant works on. However, there is a bit of platform
specific code added to OMV that is currently known to use POSIX file system
semantics, and as a result likely won't work under Windows. This means you can
either use OMV with fewer features on Windows, or help by patching it and
testing it on that platform. So far, few have wanted to use or develop on that
platform, with most preferring GNU/Linux and sometimes OSX, which are both
fully functional at this time.
Since this is an Open Source / Free Software project that I also give away for free (as in beer, free as in gratis, free as in libre), I'm unable to provide unlimited support. Please consider donating funds, hardware, virtual machines, and other resources. For specific needs, you could perhaps sponsor a feature!
$ vagrant status
There are errors in the configuration of this machine. Please fix
the following errors and try again:
Vagrant:
* Unknown configuration section 'hostmanager'.
You are seeing this error because OMV has certain requirements. One of which is a plugin that can manage hostnames. In general, we want to be able to have members of the cluster access each other via FQDN. Now, there are two ways to do this:
- Add a real DNS server somewhere and make sure the hosts can get to it.
- Modify the /etc/hosts file on each host in the vagrant cluster to have a record for all of the other machines
So, the way we can fix this error is to install the hostmanager
plugin.
$ wget https://raw.githubusercontent.com/purpleidea/oh-my-vagrant/master/extras/patch-hostmanager.sh
<snip>
2015-07-01 13:11:45 (384 MB/s) - ‘patch-hostmanager.sh’ saved [1315/1315]
$ chmod +x patch-hostmanager.sh && ./patch-hostmanager.sh
Installing the 'vagrant-hostmanager' plugin. This can take a few minutes...
Installed the plugin 'vagrant-hostmanager (1.5.0)'!
Cloning into 'vagrant-hostmanager'...
remote: Counting objects: 801, done.
remote: Total 801 (delta 0), reused 0 (delta 0), pack-reused 801
Receiving objects: 100% (801/801), 132.64 KiB | 0 bytes/s, done.
Resolving deltas: 100% (465/465), done.
Checking connectivity... done.
<snip>
sent 20,583 bytes received 319 bytes 41,804.00 bytes/sec
total size is 19,533 speedup is 0.93
Patched successfully!
Now you can run vagrant status
successfully and utilize the function of the plug-in
which allows you to modify the /etc/hosts file on each host in the cluster.
Contact me through my technical blog and I'll do my best to help. If you have a good question, please remind me to add my answer to this documentation!
Please note that there are a number of undocumented options. For more information on these options, please view the source at: https://github.com/purpleidea/oh-my-vagrant/. If you feel that a well used option needs documenting here, please contact me.
- omv.yaml: Main configuration file.
- Command line: Command line parameters.
- oh-my-vagrant.yaml: User specific configuration.
Editing the omv.yaml file is the primary way of modifying your Oh-My-Vagrant
environment. If you don't have a template, running the vagrant status
command
should cause one to get created with some sensible defaults.
While the reference docs for OMV itself are currently incomplete, you can get a
fair way given the main Vagrant documentation and
the assumption that if an omv.yaml
setting matches the name of a Vagrant box
configuration setting, then that setting in the YAML provides arguments to
the corresponding call in the Vagrantfile.
Currently undocumented.
Subnet (in CIDR notation) that will be used for virtual machines. If you're using Libvirt, make sure it does not clash with the existing virtual networks on your machine. If it does - you have to set :namespace parameter to be the same as existing network name, otherwise things will not work.
Vagrant box name (excluding .box
extension) that will be used to build a
virtual machine.
If it does not exist on the system - it will be downloaded from :boxurlprefix.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
URL pointing to a location that contains Vagrant box files. It points to https://dl.fedoraproject.org/pub/alt/purpleidea/vagrant/ by default.
Sync type to use. Valid types include rsync
and nfs
(version 3). Other
types, including nfsv4
and 9p
, will hopefully be supported in the future.
This option sets where your project folder gets synced into the machine. If you
pass an absolute path, that will be used, if you pass a relative path, then that
will be appended to the default path for that environment. In general, you will
get appended to /vagrant/
, however on an atomic host, this default is
/home/vagrant/sync/
. If you specify an empty string (the default) then no
special path will be appended, and your working directory will get synced into
the default location as specified above. Lastly, if you specify the special
path of /
, then your project will be synced into a subfolder of the same name
of your project folder, and located beneath the above default location.
For example, if you have a project (a git repository perhaps) named mgmt
, and
you want to sync the files into /vagrant/mgmt/
, then the special /
path is
the magic feature you're looking for.
Set the sync source for your vm. When left with the empty string ''
, this
defaults to the folder
in your project directory. When
folder
is empty, obviously the project directory is used by itself.
This option is particularly useful because you can pass it the ..
value, which
will pick the parent directory. This is a common hack for projects which hide
the mess of their project inside the folder
variable, but want
the whole project to get synchronized into the machine.
Currently undocumented.
Currently undocumented.
If you set this to a string, the cd
command will run with this arg after
vscreen
connects to your vm, but before the screen
command runs. This will
have the effect of putting you in your favourite working directory
automatically. This also works when using vsftp
, but not vcssh
. If you set
the cd
value to $SYNCDIR
(a string literal) or to -
(the dash) then these
are magic variables which indicate you want to cd to whichever path the
syncdir
option resolves to.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
Currently undocumented.
By default, oh-my-vagrant will create :count number of virtual
machines, all with the same settings, and generated hostnames and IP addresses.
Using the :vms
array you can define different parameters for different VMs.
Example:
:vms:
- :name: master-vm
:image: fedora-21
:disks: 1
:disksize: 10G
:memory: 1024
:cpus: 2
- :name: slave-vm
:image: centos-7.1
:count: 0
The above configuration will create 2 virtual machines: first one will have 2 CPUs and 1G of RAM assigned, as well as additional 10G hard disk, and will be based on the Fedora 21 image. The 2nd one will be created with the default values (1 CPU, 512MB of RAM), and will be based on centos-7.1 image.
Have a look at Ansible example to get an idea about how the complete configuration looks like.
Note: If you're using :vms
to define custom VMs, you might want to set
:count
parameter to zero. If you don't do this, oh-my-vagrant will always
create :count
extra VMs, which you might want or not, depending on your setup.
See this comment
for an example situation where this might be useful.
Free-form string that will be used as:
- Libvirt/VirtualBox virtual network name
- prefix for virtual machines names generation, if :vms array is not defined
If you set this to the same string as an existing network name - make sure you also set :network parameter correctly.
Set this to the number of virtual machines you want oh-my-vagrant to create. Hostnames and IP addresses will be generated automatically, and fair defaults will be used for the VMs. Example:
:namespace: testing-omv
:count: 5
Above configuration will create 5 virtual machines: testing-omv1, testing-omv2 ... testing-omv5.
See also :vms parameter documentation for information about how you can define various virtual machine parameters yourself.
Currently undocumented.
Currently undocumented.
Array of Red Hat Subscription Manager pool(s) to attach to a system. Note: even if you want to supply only one pool ID, you still have to do it with YAML list notation, like this:
:poolid:
- ff8080812bc382e3012bc3845ca000cb
If you want to pass --auto
parameter to subscription-manager command, set
:poolid:
to any arbitrary value (auto
is a good choice):
:poolid: auto
Array of Red Hat Subscription Manager repositories
to add to a system.
Prepending #
sign in front of repository name will disable this repository.
Usually it's desirable to disable all repositories from a pool, and then only
enable the repositories that are really needed (to avoid conflicts and other
related issues). To achieve this, :repos:
array should look like this:
:repos:
- '#*'
- repo1
- repo2
- ...
The above YAML represents the following sequence of commands:
subscription-manager repos --disable '*'
subscription-manager repos --enable 'repo1'
subscription-manager repos --enable 'repo2'
subscription-manager repos --enable '...'
Currently undocumented.
Currently undocumented.
Set this to true if you want to use KVM's unsafe cache mode. If you do this, you will trade data integrity on your development environment's filesystem for a noticeable speed boost. See http://libvirt.org/formatdomain.html#elementsDisks
Currently undocumented.
A space to store a string comment of your choosing. This field is not currently used anywhere by Oh-My-Vagrant.
You probably shouldn't play with this unless you've read and understand the source.
The command line arguments are currently undocumented. If you'd like to help improve these, please send a patch. They are not critical to Oh-My-Vagrant usage, because all operations can be done by editing the omv.yaml configuration file. Using the command line does make using Oh-My-Vagrant a lot faster if you're constantly changing your environment. It also makes people say "Whoa!".
This option doesn't yet exist. To add it, please send in a patch!
This is a user specific configuration file which typically goes in
~/.oh-my-vagrant.yaml
or in ~/config/oh-my-vagrant.yaml
if using a sane
default xdg configuration.
Currently undocumented.
Currently undocumented.
For example configurations, please consult the examples/ directory in the git source repository. It is available from:
https://github.com/purpleidea/oh-my-vagrant/tree/master/examples
This project will work with Vagrant version 1.6.5 and greater. It may work with certain older versions of vagrant, but they are no longer tested. Hopefully new versions of Vagrant don't introduce any regressions that break this project.
This project will work with Vagrant-Libvirt version 0.0.20 or greater, but using version 0.0.23 or greater is recommended. The same disclaimer about regressions in future versions apply.
This project is routinely tested on:
- Fedora 21+
It will probably work without incident or without major modification on:
- Debian 7+
- Fedora 20
- CentOS 5.x/6.x/7.x
- RHEL 5.x/6.x/7.x
It has not been tested by the author (but should work) on:
- Ubuntu 12.04+
It will most likely work on other GNU/Linux platforms, but testing on those platforms has been minimal due to lack of time and resources.
Testing is community supported! Please report any issues as there are a lot of features, and in particular, support for additional distros isn't well tested.
This is my personal project that I work on in my free time. Donations of funding, hardware, virtual machines, and other resources are appreciated. Please contact me if you'd like to sponsor a feature, invite me to talk/teach or for consulting.
You can follow along on my technical blog.
To report any bugs, please file a ticket at: https://github.com/purpleidea/oh-my-vagrant/issues.
Copyright (C) 2012-2015+ James Shubin and the Oh-My-Vagrant contributors
Please see the AUTHORS file for more information.