I'm attempting to manage a windows web server with the chef 'iis' cookbook and vagrant.
When I attempt to run chef-solo, it throws an error that the cookbook is not found.
The error message:
sowens-MBP:vagrant-windows sowen$ vagrant provision
==> default: Running provisioner: chef_solo...
==> default: Vagrant does not support detecting whether Chef is installed
==> default: for the guest OS running in the machine. Vagrant will assume it is
==> default: installed and attempt to continue.
Generating chef JSON and uploading...
==> default: Running chef-solo...
==> default: [2015-02-10T16:18:24-08:00] INFO: *** Chef 12.0.3 ***
==> default: [2015-02-10T16:18:24-08:00] INFO: Chef-client pid: 2508
==> default: [2015-02-10T16:18:30-08:00] INFO: Setting the run_list to ["recipe[example-webserver2012]"] from CLI options
==> default:
==> default: [2015-02-10T16:18:30-08:00] INFO: Run List is [recipe[example-webserver2012]]
==> default: [2015-02-10T16:18:30-08:00] INFO: Run List expands to [example-webserver2012]
==> default: [2015-02-10T16:18:30-08:00] INFO: Starting Chef Run for vagrant-2012-r2.nv.com
==> default: [2015-02-10T16:18:30-08:00] INFO: Running start handlers
==> default: [2015-02-10T16:18:30-08:00] INFO: Start handlers complete.
==> default: [2015-02-10T16:18:30-08:00] ERROR: Running exception handlers
==> default:
==> default: [2015-02-10T16:18:30-08:00] ERROR: Exception handlers complete
==> default: [2015-02-10T16:18:30-08:00] FATAL: Stacktrace dumped to C:/var/chef/cache/chef-stacktrace.out
==> default: [2015-02-10T16:18:30-08:00] FATAL: Chef::Exceptions::CookbookNotFound: Cookbook iis not found. If you're loading iis from another cookbook, make sure you configure the dependency in your metadata
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(2) do |config|
config.vm.box = "lmayorga1980/windows-2012r2"
config.vm.communicator = "winrm"
config.vm.network "forwarded_port", host: 3389, guest: 3389
config.vm.provider "virtualbox" do |v|
v.cpus = 2
v.memory = 2048
end
# Provisioning
config.vm.provision "chef_solo" do |chef|
# chef.cookbooks_path = ['C:\vagrant']
chef.add_recipe "example-webserver2012"
end
end
Berksfile
source "https://supermarket.chef.io"
metadata
cookbook 'iis'
metadata.rb
name 'foobar'
...
depends 'iis'
recipes/default.rb
iis_site 'Default Web Site' do
action [:stop, :delete]
end
The entire directory structure looks like this:
The cookbook was created with berks cookbook example-webserver2012.
There are 2 vagrant files, I'm using the one in the top level.
$ tree vagrant-windows/
vagrant-windows/
├── Vagrantfile
└── cookbooks
└── example-webserver2012
├── Berksfile
├── Berksfile.lock
├── CHANGELOG.md
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── README.md
├── Thorfile
├── Vagrantfile
├── attributes
├── chefignore
├── files
│ └── default
├── libraries
├── metadata.rb
├── providers
├── recipes
│ └── default.rb
├── resources
├── templates
│ └── default
└── test
└── integration
Why is cookbook 'iis' not found?
The reason the ISS cookbook isn't found is because your wrapper cookbook, example-webserver2012, declares a dependency on the IIS cookbook with Berkshelf. Unfortunately, Vagrant with the Chef solo provisioner does not know how to resolve Berkshelf dependencies out of the box. You have a couple options here.
use berks vendor to create a folder containing all the resolved cookbooks, and point the Vagrantfile at that folder.
use the vagrant berkshelf plugin to do berkshelf dependency resolution when you run vagrant provision.
From a workflow prospective I find the vagrant berkshelf plugin very useful.
P.S. In your Berksfile, you don't need to declare a dependency on the IIS cookbook, that dependency will be picked up from the metadata.rb because of the metadata line in your Berksfile.
Related
I'm trying to create an ubuntu/xenial64 vm with Vagrant and provision it using Ansible. Installed versions of tools are:
Vagrant: 2.0.0
Ansible: 2.3.2.0
Python: 2.7.10
Virtualbox: 5.1.30
These are the contents of directory in which I am running vagrant up:
├── Vagrantfile
└── playbooks
├── inventory
├── main.yml
└── vars.yml
These are the contents of Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/xenial64"
config.ssh.insert_key = true
config.vm.provider "virtualbox" do |v|
v.name = "ubuntu"
v.memory = 1024
v.cpus = 2
end
config.vm.hostname = "ubuntu"
config.vm.network :private_network, ip: "192.168.33.7"
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbooks/main.yml"
ansible.sudo = true
ansible.verbose = true
ansible.inventory_path = "playbooks/inventory"
ansible.compatibility_mode = "2.0"
end
end
playbooks/main.yml:
---
- hosts: ubuntu
become: yes
vars_files:
- vars.yml
roles:
- geerlingguy.docker
playbooks/inventory:
[ubuntu]
192.168.33.7
[ubuntu:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
playbooks/vars.yml:
docker_edition: 'ce'
docker_package: "docker-{{ docker_edition }}"
docker_package_state: present
When I run vagrant up the output is:
==> default: Checking for guest additions in VM...
default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 5.0.40
default: VirtualBox Version: 5.1
==> default: Setting hostname...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
default: /vagrant => /Users/danilo/tutorials/ansible ubuntu
==> default: Running provisioner: ansible...
default: Running ansible-playbook...
PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o IdentityFile=/Users/danilo/tutorials/ansible ubuntu/.vagrant/machines/default/virtualbox/private_key -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --connection=ssh --timeout=30 --extra-vars=ansible_user\=\'ubuntu\' --limit="default" --inventory-file=playbooks/inventory --become -v playbooks/main.yml
No config file found; using defaults
ERROR! Specified --limit does not match any hosts
Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.
However, vagrant ssh works as expected. Any ideas what I may be missing?
Firstly, if you use hosts: ubuntu then you must define named machine:
config.vm.define "ubuntu" do |ubuntu|
ubuntu.vm.provision "ansible" do |ansible|
ansible.playbook = "playbooks/main.yml"
ansible.sudo = true
ansible.verbose = true
ansible.inventory_path = "playbooks/inventory"
ansible.compatibility_mode = "2.0"
end
end
Otherwise change to hosts: default in the play.
But then...
I have no idea why you try to provision via 192.168.33.7 - it seems completely unnecessary for this use case - you can remove the ansible.inventory_path from Vagrantfile
in the same inventory file you specify user vagrant which is not configured on ubuntu/xenial64 box
ansible.sudo is also not necessary in the Vagrantfile
running Ansible this way on ubuntu/xenial64 way will likely fail for the lack of Python 2
I inherited a project that hasn’t been deployed in a couple of years. It was originally set-up for local deployment on a Vagrant machine using Chef.
When I run the the vagrant up command, I get an error that it is not finding some cookbooks. First it was not finding cookbooks in the cookbooks directory specified in the Vagrantfile. I fixed this by adding a metadata.rb file to the cookbook i was trying to run. It looks like
#cookbooks/app/metadata.rb
depends "openssl" # this is in the cookbooks directory
depends "build-essential" # this in the cookbooks directory
depends "git" # this in the cookbooks directory
Now when I run vagrant up it breaks in the git cookbook because it cannot find one of it’s dependencies, dmg (which I don’t even need).
So how do I install these cookbooks dependencies so that it will run. Should these cookbooks be installed on my host machine (i.e. my Mac which hosts the Vagrant box) or on the Vagrant itself.
I have downloaded the ChefDK and have Berkshelf but am not sure how to use it on and existing project. Also based on the solo.rb file it looks like it is looking for cookbooks in /etc/chef/cookbooks.
# solo.rb
log_level :info
cookbook_path "/etc/chef/cookbooks"
json_attribs "/etc/chef/cookbooks/node_staging.json"
role_path "/etc/chef/roles"
Here is sample output from running vagrant up.
==> default: Running chef-solo...
==> default: stdin: is not a tty
==> default: [2015-11-30T19:46:31+00:00] INFO: Forking chef instance to converge...
==> default: [2015-11-30T19:46:31+00:00] WARN:
==> default: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
==> default: SSL validation of HTTPS requests is disabled. HTTPS connections are still
==> default: encrypted, but chef is not able to detect forged replies or man in the middle
==> default: attacks.
==> default:
==> default: To fix this issue add an entry like this to your configuration file:
==> default:
==> default: ```
==> default: # Verify all HTTPS connections (recommended)
==> default: ssl_verify_mode :verify_peer
==> default:
==> default: # OR, Verify only connections to chef-server
==> default: verify_api_cert true
==> default: ```
==> default:
==> default: To check your SSL configuration, or troubleshoot errors, you can use the
==> default: `knife ssl check` command like so:
==> default:
==> default: ```
==> default: knife ssl check -c /tmp/vagrant-chef/solo.rb
==> default: ```
==> default:
==> default: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
==> default: Starting Chef Client, version 11.18.12
==> default: [2015-11-30T19:46:31+00:00] INFO: *** Chef 11.18.12 ***
==> default: [2015-11-30T19:46:31+00:00] INFO: Chef-client pid: 1844
==> default: [2015-11-30T19:46:32+00:00] INFO: Setting the run_list to ["role[vagrant]"] from CLI options
==> default: [2015-11-30T19:46:32+00:00] INFO: Run List is [role[vagrant]]
==> default: [2015-11-30T19:46:32+00:00] INFO: Run List expands to [app::default]
==> default: [2015-11-30T19:46:32+00:00] INFO: Starting Chef Run for geosurvey
==> default: [2015-11-30T19:46:32+00:00] INFO: Running start handlers
==> default: [2015-11-30T19:46:32+00:00] INFO: Start handlers complete.
==> default: Compiling Cookbooks...
==> default:
==> default: Running handlers:
==> default: [2015-11-30T19:46:32+00:00] ERROR: Running exception handlers
==> default: Running handlers complete
==> default:
==> default: [2015-11-30T19:46:32+00:00] ERROR: Exception handlers complete
==> default: [2015-11-30T19:46:32+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: Chef Client failed. 0 resources updated in 1.06392657 seconds
==> default: [2015-11-30T19:46:32+00:00] ERROR: Cookbook dmg not found. If you're loading dmg from another cookbook, make sure you configure the dependency in your metadata
==> default: [2015-11-30T19:46:32+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
Vagrant on its own doesn't support Berkshelf integration. There is a plugin available for it (vagrant-berkshelf) which will pull in dependencies and sync them to the VM, but it isn't recommended given that it can be a bit flaky. Test Kitchen (with kitchen-vagrant) is generally easier. You can also do it manually by using the berks vendor command to download the deps and dump them into a folder structure chef-solo can use.
I have similar problems and managed to solved them party.
Installing vagrant berkshelf plugin solves it party. As I understand one has to go through each cookbook and type barks install appart from configuring vagrant barkshelf like this:
config.berkshelf.enabled = true
config.berkshelf.berksfile_path = "./cookbooks/database/Berksfile"
But I'm exploring this vendor solution that didn't work quite well.
As far I understand to coderanger if I had a a directory named "./cookbooks-source" and within have a bunch of cookbooks (cb1, cb2, cb3, ...) I would have to iterate each of them and type something like
berks vendor ../../cookbooks
but then each of these cookbooks dependencies might conflict with each other ? Plus I find it quite inconvenient. Also exploring berks package but just don't know how to hook it up to vagrant.
I'm trying to set up Vagrant for web development, on Windows 8.1. I've already hit the problem undefined method “cheffish” for nil:NilClass, so am using Vagrant 1.7.4 with Chef 12.3.0.
I can't solve this error:
ERROR: You must specify at least one cookbook repo path
from:
c:\web\project>vagrant provision
==> default: The cookbook path 'c:/web/project/cookbooks' doesn't exist. Ignoring...
==> default: The cookbook path 'c:/web/project/site-cookbooks' doesn't exist. Ignoring...
==> default: Chef 12.3.0 Omnibus package is already installed.
==> default: Running provisioner: chef_solo...
==> default: Detected Chef (latest) is already installed
Generating chef JSON and uploading...
==> default: Running chef-solo...
==> default: stdin: is not a tty
==> default: [2015-07-21T10:08:00+00:00] INFO: Forking chef instance to converge...
==> default: Starting Chef Client, version 12.3.0
==> default: [2015-07-21T10:08:00+00:00] INFO: *** Chef 12.3.0 ***
==> default: [2015-07-21T10:08:00+00:00] INFO: Chef-client pid: 1813
==> default: [2015-07-21T10:08:01+00:00] INFO: Setting the run_list to ["recipe[apt]", "recipe[nodejs]", "recipe[postgresql]", "recipe[postgresql::ser
ver]", "recipe[postgresql::client]"] from CLI options
==> default: [2015-07-21T10:08:01+00:00] INFO: Run List is [recipe[apt], recipe[nodejs], recipe[postgresql], recipe[postgresql::server], recipe[postgr
esql::client]]
==> default: [2015-07-21T10:08:01+00:00] INFO: Run List expands to [apt, nodejs, postgresql, postgresql::server, postgresql::client]
==> default: [2015-07-21T10:08:01+00:00] INFO: Starting Chef Run for vagrant-ubuntu-trusty-64
==> default: [2015-07-21T10:08:01+00:00] INFO: Running start handlers
==> default: [2015-07-21T10:08:01+00:00] INFO: Start handlers complete.
==> default: Running handlers:
==> default: [2015-07-21T10:08:01+00:00] ERROR: Running exception handlers
==> default: Running handlers complete
==> default: [2015-07-21T10:08:01+00:00] ERROR: Exception handlers complete
==> default: [2015-07-21T10:08:01+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: Chef Client failed. 0 resources updated in 0.736170145 seconds
==> default: [2015-07-21T10:08:01+00:00] ERROR: You must specify at least one cookbook repo path
==> default: [2015-07-21T10:08:01+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
Vagrantfile
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Use Ubuntu 14.04 Trusty Tahr 64-bit as our operating system
config.vm.box = "ubuntu/trusty64"
# Configurate the virtual machine to use 2GB of RAM
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
end
# Forward the Rails server default port to the host
config.vm.network :forwarded_port, guest: 8000, host: 8000
# config.omnibus.chef_version = :latest
config.omnibus.chef_version = "12.3.0"
# Use Chef Solo to provision our virtual machine
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.add_recipe "apt"
chef.add_recipe "nodejs"
chef.add_recipe "postgresql"
chef.add_recipe "postgresql::server"
chef.add_recipe "postgresql::client"
chef.json =
{
postgresql: {
users: [
{
"username" => "postgres",
"password" => "password",
"superuser" => true,
"replication" => false,
"createdb" => true,
"createrole" => false,
"inherit" => true,
"replication" => false,
"login" => true
}
]
}
}
end
end
Cheffile
site "http://community.opscode.com/api/v1"
cookbook 'apt'
cookbook 'nodejs'
cookbook 'build-essential'
cookbook 'postgresql', git: 'https://github.com/phlipper/chef-postgresql'
This vagrant-berkshelf issue looked similar, but deleting .vagrant.d, reloading and provisioning again didn't solve it.
What's causing this?
Thanks!
I installed Chef Dev Tools as this is the simplest way to install Berkshelf 3.0 on Windows. I set up a Berksfile in my project, based on my Cheffile, and enabled Berkshelf in the Vagrantfile. Now it provisions using Berkshelf, and it works.
Given there was no indication that Vagrant was using Berkshelf, I'm still not convinced that Berkshelf was the issue.
It would still be helpful to know how to install the latest Berkshelf version without Chef Dev Tools on Windows.
I created a basic vagrant box and config provisioning as below
config.vm.provision :chef_solo do |chef|
chef.add_recipe "apache2"
chef.json = { :apache => { :default_site_enabled => true } }
end
I also add cookbook to my project
git submodule add https://github.com/svanzoest-cookbooks/apache2/ cookbooks/apache2
But when I run vagrant provision, I get this
==> default: [2015-03-26T14:55:52+00:00] INFO: Forking chef instance to converge...
==> default: [2015-03-26T14:55:52+00:00] INFO: *** Chef 12.1.2 ***
==> default: [2015-03-26T14:55:52+00:00] INFO: Chef-client pid: 1130
==> default: [2015-03-26T14:55:54+00:00] INFO: Setting the run_list to ["recipe[apache2]"] from CLI options
==> default: [2015-03-26T14:55:54+00:00] INFO: Run List is [recipe[apache2]]
==> default: [2015-03-26T14:55:54+00:00] INFO: Run List expands to [apache2]
==> default: [2015-03-26T14:55:54+00:00] INFO: Starting Chef Run for precise32
==> default: [2015-03-26T14:55:54+00:00] INFO: Running start handlers
==> default: [2015-03-26T14:55:54+00:00] INFO: Start handlers complete.
==> default: [2015-03-26T14:55:54+00:00] ERROR: Running exception handlers
==> default: [2015-03-26T14:55:54+00:00] ERROR: Exception handlers complete
==> default: [2015-03-26T14:55:54+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: [2015-03-26T14:55:54+00:00] ERROR: Cookbook iptables not found. If you're loading iptables from another cookbook, make sure you configure the dependency in your metadata
==> default: [2015-03-26T14:55:54+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Maybe iptables cookbook is required, so I add it. And then I get this message
==> default: [2015-03-26T14:58:32+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: [2015-03-26T14:58:32+00:00] ERROR: Cookbook logrotate not found. If you're loading logrotate from another cookbook, make sure you configure the dependency in your
==> default: [2015-03-26T14:58:32+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
logrotate cookbook is required?
Why does it continuously require cookbook? What is metadata here?
Can anyone help me?
Cookbooks can have dependencies to other cookbooks. This allows them to rely on functionality provided by these other cookbooks.
In your case, your apache2 cookbook depends on the iptables and the logrotate cookbooks. You can check this in each cookbook's metadata.rb file. In case of your apache2 cookbook, you can find the metadata.rb file on GitHub.
Note that cookbooks can also have recursive dependencies, i.e. they can have further dependencies which must all be fulfilled. Because if this, it is often recommended to manage your cookbooks with a tool like Berkshelf or Librarian which can download all cookbook dependencies automatically and consistent.
I have a few directories with different Mercurial histories that I am working on in parallel. They all have the same Vagrantfile so it would be natural to use just one instance for all of them.
But when I run "vagrant up" in a new directory, it starts from linking the existent VM, setting up the environment, and so on.
How do I share the Vagrant instance between different directories?
UPDATE: my directory structure:
\
Vagrantfile
puppet
*.pp
support
nginx.conf
uwsgi.development.ini
other_repo_related_files_and_dirs
Well, if you want to share some directories with the same Vagrant's instance, you can configure the Vagrantfile.
This is an example with two VM (app and web), using the same box (ubuntu-12.04) and the same Vagrantfile. Each instance have two folders (one folder by VM).
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define 'app' do |app_config|
app_config.vm.box = 'ubuntu-12.04'
app_config.vm.host_name = 'app'
app_config.vm.network "private_network", ip: "192.168.33.33"
app_config.vm.synced_folder "app_config", "/app_config"
end
config.vm.define 'web' do |web_config|
web_config.vm.box = 'ubuntu-12.04'
web_config.vm.host_name = 'web'
web_config.vm.network "private_network", ip: "192.168.33.34"
web_config.vm.synced_folder "web_config", "/web_config"
end
end
The app machine has an app_config folder and the web machine have a web_config folder(these folders are in the same level of the Vagrantfile file).
When you enter to each VM with the vagrant ssh command you can see each folder.
This is into app machine.
roberto#rcisla-pc:~/Desktop/multiple$ vagrant ssh app
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)
* Documentation: https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Mon Jan 27 13:46:36 2014 from 10.0.2.2
vagrant#app:~$ cd /app_config/
vagrant#app:/app_config$ ls
app_config_file
This is into web machine.
roberto#rcisla-pc:~/Desktop/multiple$ vagrant ssh web
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)
* Documentation: https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Mon Jan 27 13:47:12 2014 from 10.0.2.2
vagrant#web:~$ cd /web_config/
vagrant#web:/web_config$ ls
web_config_file
vagrant#web:/web_config$
And this is the structure for my directory.
.
├── **app_config**
│ └── *app_config_file*
├── attributes
├── Berksfile
├── Berksfile.lock
├── chefignore
├── definitions
├── files
│ └── default
├── Gemfile
├── libraries
├── LICENSE
├── metadata.rb
├── providers
├── README.md
├── recipes
│ └── default.rb
├── resources
├── templates
│ └── default
├── test
│ └── integration
│ └── default
├── Thorfile
├── Vagrantfile
├── Vagrantfile~
└── **web_config**
└── *web_config_file*
I hope this help you.
Just thinking out loud here. Not sure if it's a solution that meets your demands.
If you set-up a directory structure like this
/Main
/projects
/mercurial_history_1
/mercurial_history_2
/mercurial_history_3
/puppet
/modules
/manifests
default.pp
Vagrantfile
I'm not sure what kind of projects you are running, but if you are running a apache webserver for example. You could specify a separate vhost for every mercurial project inside the VM. So you can point the DocumentRoot to the specific mercurial project.
For this solution you have to add the following line in the Vagrantfile
config.vm.network "private_network", ip: "22.22.22.11" <- Just an example IP
Then on you host machine you can update the hosts file with the IP and corresponding vhostname servername. It's a little bit more work, but you can add vhosts using a provisioner to make life easier ;)
This way you only have one VM running that runs al your mercurial projects