Creating Virtual Machines With Vagrant
Creating virtual machines can be a complex process. Why not automate it?
Vagrant is a command line utility for creating virtual machines quickly. In this tutorial you will create a Linux virtual machine running Apache and configure it to serve web pages in the current folder.
You can complete this tutorial on Windows or macOS. You will need VirtualBox installed and a fast Internet connection.
Installing Vagrant
Installing Vagrant is as easy as installing any other program. Visit https://www.vagrantup.com/ and download the installer for your operating system. Run the installer and accept any defaults presented.
Once Vagrant has finished its installation process, open a new command line interface and type
$ vagrant
to ensure that it works. You’ll see something like this:
Usage: vagrant [options] <command> [<args>]
-v, --version Print the version and exit.
-h, --help Print this help.
Common commands:
...
up starts and provisions the vagrant environment
version prints current and latest Vagrant version
For help on any individual command run `vagrant COMMAND -h`
Additional subcommands are available, but are either more advanced
or not commonly used. To see all subcommands, run the command
`vagrant list-commands`.
Vagrant is ready to go. Now you can configure your first virtual machine.
Creating A Machine
We’re going to create a basic Ubuntu machine using a “base box.” This is a preconfigured virtual machine ready for use with Vagrant. This machine already has the OS installed for you. So instead of downloading an ISO that you have to manually install when you the machine, you just download a ready-made machine that “just works.”
First, open a command prompt or terminal and create a folder to work in:
$ mkdir vagrant
$ cd vagrant
Then execute this command:
$ vagrant init hashicorp/precise64
This creates a new file called Vagrantfile
which defines the virtual
machine’s settings. It configured it to use a base box for Ubuntu 12.04 LTS
provided by Hashicorp, the creators of Vagrant.
Next, run
$ vagrant up
When you first run this command, it will check to see if the base box is on your computer. And since this is the first time you’ve tried this, it won’t be found, so it’ll download it:
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
default: URL: https://atlas.hashicorp.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
default: Downloading: https://atlas.hashicorp.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
default: Progress: 74% (Rate: 6371k/s, Estimated time remaining: 0:00:13)
Next, it configures the machine:
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'hashicorp/precise64' is up to date...
==> default: Setting the name of the VM: apache_default_1456513889780_29262
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)
Once it’s configured, it boots and connects to the machine over SSH with a user called vagrant
that it sets up:
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
Vagrant uses public and private key pairs for logging in instead of passwords, and it needs to generate new keys whenever we create a new machine. The default key is just there to get things started. But it’s not secure since everyone has a copy of the default key when Vagrant is installed. Think of this like a password reset from “12345” to something really complex.
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
Next, it verifies if guest additions are configured right. In some cases you may see this message:
==> 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: 4.2.0
default: VirtualBox Version: 4.3
For what we’re doing, you can ignore this message and move on.
The last thing Vagrant does is configure a shared folder. Any file we create in the current working folder will be
available in a folder called /vagrant
within the virtual machine:
==> default: Mounting shared folders...
default: /vagrant => /Users/brianhogan/tmp/apache
At this point, the virtual machine is running.
Type the command
$ vagrant ssh
to log in.
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)
* Documentation: https://help.ubuntu.com/
New release '14.04.4 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Welcome to your Vagrant-built virtual machine.
Last login: Fri Feb 26 19:18:43 2016 from 10.0.2.2
vagrant@precise64:~$
Find the machine’s IP address with ifconfig
:
`ifconfig eth0 | grep 'inet addr`
Now type exit
to exit out of the machine.
Now, destroy this machine. We’re going to build it again.
$ vagrant destroy
You’ll be asked if you want to destroy the machine. Enter y
:
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Forcing shutdown of VM...
==> default: Destroying VM and associated drives...
And that’s it. Now let’s do something more interesting.
Creating A Web Server Machine
We’re going to use Vagrant to quickly set up Ubuntu and the Apache web server to serve HTML files from the current folder. That means we need an HTML file.
In the current folder, create the file index.html
using your favorite text editor. Inside of this file,
create an h1
tag with your name in it. Here’s an example file:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>Brian's site</title>
<link rel="stylesheet" href="stylesheets/style.css">
</head>
<body>
<h1>Brian Hogan</h1>
</body>
</html>
Next, edit the Vagrantfile
. We’re going to uncomment several sections within the file.
Setting the Name
By default, Vagrant calls
your machine default
. And that’s not good if you want to have multiple virtual machines
managed by Vagrant. So naming your machine will help keep things clear.
We actually have two names to change. First we want to change the name that Vagrant uses to reference the machine. And then we want to change the name that VirtualBox uses to create the machine.
First, locate this section:
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "hashicorp/precise64"
Right below that section, add this line to define the name of the Vagrant machine:
config.vm.define "bhogan_apache"
But use your CVTC Username, not mine.
Next, locate this section:
# 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 = "1024"
# end
This is the section that configures the VirtualBox virtual machine. It’s commented out, so VirtualBox will
use default settings. The comments here explain the options. By default, the vb.gui
option is turned off. This
way VirtualBox will not pop up and open when you start a machine, which is great for servers.
Remove the hash marks from the first and last lines of this section, and delete the other lines. Make sure it looks like this:
config.vm.provider "virtualbox" do |vb|
end
Then, in between these lines, add this line to give your machine a name. This is the name that will display in VirtualBox’s user interface.
vb.name = "bhogan_apache"
Again, use your CVTC Username, not mine.
The section should now look like this:
config.vm.provider "virtualbox" do |vb|
vb.name = "bhogan_apache"
end
But with your own username, of course.
Configure Networking
Our machine will run the Apache web server, but in order to access it, we’ll have to do some port forwarding. Apache runs on port 80. And so we’ll
configure Vagrant to forward traffic from our computer to this virtual machine. When we access localhost:8080
in our web browser, the
request will go to our virtual machine and be served by Apache!
Locate this line:
# config.vm.network "forwarded_port", guest: 80, host: 8080
and remove the hash mark in front of the line to uncomment it. Piece of cake! All requests to our local machine’s port 8080 get routed to the virtual machine’s port 80.
Sharing files
We want to serve any files in our current folder with Apache running in the virtual machine. Vagrant makes this easy to do. Locate this part of the configuration file:
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
Below that, add a line of configuration that maps the current folder (.
) to /var/www
, the folder Apache uses to
serve web pages.
config.vm.synced_folder ".", "/var/www"
And that’s it. All the files in this folder will be synchronized to the /var/www
folder within the virtual machine!
Automatically Install Apps
When we create our machine, we want to update the OS to install any security fixes, and we want to install Apache. Find this section:
# config.vm.provision "shell", inline: <<-SHELL
# sudo apt-get update
# sudo apt-get install -y apache2
# SHELL
When a machine is “provisioned”, or built from scratch, this section runs. And by default, it has almost exactly what we need. So remove the comments from this section so it looks like this:
config.vm.provision "shell", inline: <<-SHELL
sudo apt-get update
sudo apt-get install -y apache2
SHELL
Save the configuration file and return to your command prompt or terminal.
Creating the machine
Just like last time, run the vagrant up
command to create the machine.
$ vagrant up
This time, you won’t have to download the base box, because it’s already there. It will see if the base box needs an update though:
Bringing machine 'default' up with 'virtualbox' provider...
==> bhogan_apache: Importing base box 'hashicorp/precise64'...
==> bhogan_apache: Matching MAC address for NAT networking...
==> bhogan_apache: Checking if box 'hashicorp/precise64' is up to date...
==> bhogan_apache: Setting the name of the VM: bhogan_apache
Then it configures your network:
==> bhogan_apache: Clearing any previously set network interfaces...
==> bhogan_apache: Preparing network interfaces based on configuration...
bhogan_apache: Adapter 1: nat
==> bhogan_apache: Forwarding ports...
bhogan_apache: 80 (guest) => 8080 (host) (adapter 1)
bhogan_apache: 22 (guest) => 2222 (host) (adapter 1)
It then boots the machine and replaces the key:
==> bhogan_apache: Booting VM...
==> bhogan_apache: Waiting for machine to boot. This may take a few minutes...
bhogan_apache: SSH address: 127.0.0.1:2222
bhogan_apache: SSH username: vagrant
bhogan_apache: SSH auth method: private key
bhogan_apache:
bhogan_apache: Vagrant insecure key detected. Vagrant will automatically replace
bhogan_apache: this with a newly generated keypair for better security.
bhogan_apache:
bhogan_apache: Inserting generated public key within guest...
bhogan_apache: Removing insecure key from the guest if it's present...
bhogan_apache: Key inserted! Disconnecting and reconnecting using new SSH key...
==> bhogan_apache: Machine booted and ready!
After checking the guest additions, it attempts to create the shared folders you told it to create:
==> bhogan_apache: Mounting shared folders...
==> bhogan_apache: Mounting shared folders...
bhogan_apache: /var/www => /Users/brianhogan/tmp/apache
Finally, it runs the provisioning script we asked it to run.
==> bhogan_apache: Running provisioner: shell...
bhogan_apache: Running: inline script
==> bhogan_apache: stdin: is not a tty
==> bhogan_apache: Ign http://us.archive.ubuntu.com precise InRelease
==> bhogan_apache: Get:1 http://us.archive.ubuntu.com precise-updates InRelease [55.7 kB]
==> bhogan_apache: Get:2 http://security.ubuntu.com precise-security InRelease [55.7 kB]
...
==> bhogan_apache: Fetched 6,312 kB in 5s (1,100 kB/s)
And then installs Apache!
==> bhogan_apache: Reading package lists...
==> bhogan_apache: Reading package lists...
==> bhogan_apache: Building dependency tree...
==> bhogan_apache:
==> bhogan_apache: Reading state information...
==> bhogan_apache: The following extra packages will be installed:
==> bhogan_apache: apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1
==> bhogan_apache: libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
==> bhogan_apache: Suggested packages:
==> bhogan_apache: www-browser apache2-doc apache2-suexec apache2-suexec-custom
==> bhogan_apache: openssl-blacklist
==> bhogan_apache: The following NEW packages will be installed:
==> bhogan_apache: apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common
==> bhogan_apache: libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
==> bhogan_apache: 0 upgraded, 10 newly installed, 0 to remove and 185 not upgraded.
==> bhogan_apache: Need to get 1,859 kB of archives.
==> bhogan_apache: After this operation, 5,697 kB of additional disk space will be used.
==> bhogan_apache: Get:1 http://us.archive.ubuntu.com/ubuntu/ precise/main libapr1 amd64 1.4.6-1 [89.6 kB]
...
==> bhogan_apache: Setting up apache2-mpm-worker (2.2.22-1ubuntu1.10) ...
==> bhogan_apache: * Starting web server apache2
==> bhogan_apache: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
==> bhogan_apache: ...done.
==> bhogan_apache: Setting up apache2 (2.2.22-1ubuntu1.10) ...
==> bhogan_apache: Setting up ssl-cert (1.0.28ubuntu0.1) ...
==> bhogan_apache: Processing triggers for libc-bin ...
==> bhogan_apache: ldconfig deferred processing now taking place
And if you visit http://localhost:8080 in your browser, you’ll see the web page you created earlier!
Log into the machine
Use
$ vagrant ssh
to log into the machine. Then use the cat
command to verify the contents of the file /var/www/index.html
to
make sure it’s yours:
$ cat /var/www/index.html
And sure enough, you see the file you created.
Type
$ exit
to exit the virtual machine.
Then type
$ vagrant halt
to gracefully shut down this virtual machine. You can start it again with
vagrant up
whenever you need it.
Using Vagrant Machines Directly Through VirtualBox
Behind the scenes, Vagrant is just making VirtualBox do the things you’d normally set up yourself, but in a faster way.
Open VirtualBox and you’ll find your machine listed in the sidebar. Start it up like normal and you’ll be able to
run it as if you’d installed it yourself. Log in with the username vagrant
and the password vagrant
.
To shut the machine down, either send the shutdown signal, or go back to your terminal and issue the
$ vagrant halt
command again. Vagrant will tell VirtualBox what to do.
Wrapping Up
In this tutorial, you learned how to create Linux virtual machines with Vagrant. You can use this to create development environments to test your code, or quickly prepare production machines. By default, Vagrant uses VirtualBox, but you can use different providers to use Vagrant to create machines on Amazon’s EC2 offerings or on other cloud providers.
In addition, you can use Vagrant to set up Windows virtual machines.
Exercises
First, ensure you have a working Apache webserver configured exactly as stated in this tutorial.
Then, create a Widnows virtual machine with Vagrant, with the following settings:
- Initialize a new Vagrant project in a new folder. Create the folder, and then inside that folder, create the Vagrantfile.
- Use
modernIE/w7-ie11
as the base box. - Name the machine
yourname_windows7
where youranme is your CVTC username. Remember to do this in both the main configuration and the provider configuration. - Ensure the virtual machine has 1024 GB of Ram when you create it.
- Ensure that the GUI for VirtualBox is enabled.
- Delete all other commented lines in the configuration file so only the active configuration remains.