When you need a VM, you just build one manually. When you need two, you just build two manually. When you need three or more and with changing network topologies, you wonder if there is no better way to do this.
I needed 4 VMs: 1 doing NAT/acting as a router, and 3 for a typical cluster stuff like etcd, cassandra, object storage etc.
So something better than manual build was needed. OpenStack is a possible solution but that turned out to be surprisingly complicated and overkill. Vagrant looked better.
Things I learned so far:
- Using Vagrant for a simple VM “out of the box” (“box” is basically the template) is very simple.
- You connect to the single VM by “vagrant ssh”
- Similar to Docker, you can import files (e.g. config files) and run scripts inside the VM
config.vm.provision "shell", inline: <<-SHELL
- Similar to Docker, you can mount local directories into the VM:
config.vm.synced_folder "./data", "/vagrant"
- Modifying VM parameter is not difficult:
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
# vb.gui = true
# Customize the amount of memory on the VM:
vb.memory = "512"
vb.cpus = 1
vb.linked_clone = true
vb.customize ["modifyvm", :id, "--vram", "9"]
- To modify an existing box or making a new one, you can do that manually, or via a “packer”. The manual one is easy:
- Enter an existing box (easiest one: console, account vagrant, same password)
- Do your stuff
- Outside the box run:
vagrant package --base VMNAME
mv package.box some-more-sensible-name.box
vagrant box add some-more-sensible-name.box some-name
- You can now use “some-name” as box name for new VMs
- Keep the box files. And the Vagrantfile. That’s all beside replicated/copied/mounted directories.
- Multiple VMs are easily created, and need some extra network configuration. Like this:
config.vm.define "web" do |web|
config.vm.define "db" do |db|
- Since I have 2 bridged interfaces, I have to name the one I like. Both VMs promptly aquire IPs via DHCP on my internal network.
config.vm.network "public_network", bridge: "enp3s0"
Additional interesting links: