IP lookup for Vagrant private networking
I haven't posted in ages and given I'm doing so much interesting stuff with SpatialBuzz these days, I felt I needed to post something, however short but sweet.
I spin up a lot of dev instances with Vagrant and VirtualBox on OS X these days and
needed them to be host addressable on fixed IPs. I also wanted a single source for managing said IPs.
After trying several Vagrant plugins, playing with DHCP and tweaking pf
rules, the
easiest solution I found was a local DNS server and getting the Vagrantfile
to
look up its own IP.
30-second guide to local DNS on OS X1
- Install
dnsmasq
via Homebrew -
Add your desired homename and IPs to the end of the default config file
/usr/local/etc/dnsmasq.conf
in the formataddress=/<host name>/<IP address>
e.g.:-address=/db.vagrant.dev/192.168.2.10 address=/web.vagrant.dev/192.168.2.11
-
Start your local DNS server with the following command (and stop it with
unload
):-sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
-
Tell OS X to use it for a domain by creating the file
/etc/resolver/<domain>
e.g./etc/resolver/vagrant.dev
with the contents:-nameserver 127.0.0.1
-
Check the resolver is listed with:-
scutil --dns
-
Query it directly with:-
dig db.vagrant.dev @127.0.0.1
Vagrantfile
Here's a basic Vagrantfile
to configure a single instance with the host-only network address read from DNS. As the host name is specified
as a parameter, this works for multi-machine setups too. The VM is both addressable via vagrant ssh
and SSH directly to the host name.
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
# Set default to virtualbox unless otherwise specified
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'virtualbox'
# hostname.wamonite.com: private IP address read from local DNS
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "hashicorp/precise64"
# Set the hostname
config.vm.hostname = "web.vagrant.dev"
# Read the IP address from local DNS and set as private network IP
ip = Socket::getaddrinfo(config.vm.hostname, 'http', nil, Socket::SOCK_STREAM)[0][3]
config.vm.network "private_network", ip: ip
end
Guest VM lookups
On VirtualBox the DNS server is available on the .1 address of the specified class C network, so VMs can address each other if the name
resolution for the guest OS is configured appropriately. In the above example, for a Linux host /etc/resolv.conf
would need to contain:-
nameserver 192.168.2.1
domain vagrant.dev
-
Another guide with detailed commands can be found at 'Never touch your local /etc/hosts file in OS X again' ↩
Posted Sat 12 Jul '14 in Dev (Vagrant, OS X, VirtualBox)