Managing and provisioning VMs

Port Forwarding

An important setting for my particular use of VMs is port forwarding, which allows me to access services running inside the VM from the host. Vagrant supports this type of networking as well. I can tweak the Vagrantfile to set up a port on the host machine to forward to a port in the VM. In effect, this allows me to access the services running inside the VM.

For instance, if I forward the standard port for HTTP content (port 80) in the VM to port 8081 on the host, then I can access the web server running in the VM by pointing the web browser on the host machine to http://localhost:8081. In the background, the traffic sent to port 8081 is actually forwarded to port 80 on the VM.

Fire up the Vagrantfile in a text editor and enter the following parameter: "forwarded_port", guest: 80, host: 8081

With this parameter, I am instructing Vagrant to forward port 80 from inside the VM to port 8081 on the host. Save the file and restart the VM:

$ vagrant reload

To check the settings, you can use the SimpleHTTPServer module in Python to read the contents of the /vagrant directory. Once the VM is up and running, SSH into it and bring the web server online with:

$ vagrant ssh
[vagrant@localhost ~]$ cd /vagrant
[vagrant@localhost ~]$ sudo python -m SimpleHTTPServer 80

Now open a browser on the host and point it to http://localhost:8081, and you'll get a /vagrant directory listing served from inside the VM. You can now tweak the example to install any service inside the VM and modify the Vagrantfile to shuttle traffic between the host and the VM.

Provisioning VMs

At the moment, the CentOS VM is pretty basic. To harness Vagrant's power, you'll have to flesh out the installation. You can do this in a couple of ways. You can use the CentOS package manager to add packages manually. However, the better option is to automatically install the software as part of the VM's creation process, which is known as provisioning. Vagrant supports provisioning with shell scripts, Chef, or Puppet, and you can add more provisioners via plugins.

I personally prefer provisioning via shell scripts as opposed to Chef or Puppet, which are overkill for my simple requirements. Working with shell scripts is fairly straightforward. All you need to do is simply gather all the required operations that need to be handled automatically inside a script (see Listing 1).

Listing 1

Provisioning Shell Script

01 $ sudo nano
03 # !/usr/bin/env bash
05 echo "Now installing the Apache web server quietly in the background"
06 yum update httpd > /dev/null 2>&1
07 yum install -y httpd > /dev/null 2>&1
08 systemctl start httpd

Line 3 of Listing 1 specifies which shell to use to execute the rest of the file (bash in this case). The script will then display that it's about to install the Apache web server without any further prompts or outputs, so as to not fill the screen with unnecessary output.

Vagrant will run the script as root, which is why there is no need to actually use sudo on lines 6, 7, and 8. The -y flag tells yum to automatically respond "yes" to any prompts. This is important since I am provisioning the VMs automatically. Because there is no human interaction, if yum were to ask for confirmation, the script would simply never finish. As previously mentioned, yum's output is sent to /dev/null instead of the terminal.

Once the shell script has been created, the next step is to configure Vagrant to use it to provision the VMs during boot. For this, you can point to the script from the Vagrantfile with the following parameter:

config.vm.provision "shell", path: ""

This tells Vagrant to provision the machine with the shell provisioner and to use the shell script named that's available in the project directory (~/demo on the host).

Now bring up or reload the VM. Thanks to this parameter, Vagrant will execute the script after the VM is up and running (Figure 4).

Figure 4: Once a VM has been provisioned, the script will be ignored on subsequent reboots.

GUI Guest

While Vagrant is primarily used to create and provision headless VMs, you can also create a VM with a full blown graphical desktop. Open the Vagrantfile, scroll down, and uncomment the following lines or add them manually:

config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "1024"

These lines tell Vagrant to enable the VirtualBox GUI mode and allocate 1024MB of RAM to it. Once you've saved the changes, you can restart the VM. This time, it'll pop out a VirtualBox window and drop you at the shell login prompt. Even though Vagrant uses key-based authentication by default, it is a general convention to set the password for the "vagrant" user to vagrant. You can use these login credentials to log into the VM manually.

Since the VM I specified earlier is a CentOS server distribution, you'll have to pull in packages for a full-blown CentOS graphical desktop, which is fairly well-documented [5], after logging into this VM.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Perl – Vagrant Package

    The Vagrant package provides easy management of virtual machines with VirtualBox as the hypervisor on the command line. Provisioning tools like Puppet let customers try out products in pre-installed environments.

  • Perl – Elasticsearch

    Websites often offer readers links to articles about similar topics. Using Elasticsearch, the free search engine, is one way to find related documents instantly and automatically.

  • YunoHost

    YunoHost offers a wide range of services on a proven Debian platform that you can host yourself.

  • Docker

    Docker is an economical alternative to conventional virtualization. Because each Docker container shares the underlying operating system, it enjoys the resource isolation and allocation benefits of VMs but is much more portable and efficient.

comments powered by Disqus