Vagrant, vSphere and Photon OS

by admin

I wanted to have a look at using Vagrant with vSphere to help provision a dev environment, mainly for an excuse to have a look at Vagrant. This post will cover the steps I used to get Vagrant up and running, and able to provision a VM on an ESXi host, via vCenter.

To start with, we need a place to run Vagrant. I decided on using a minimal Centos 7 build as my Vagrant host. After installing Centos, the Ruby package will need to be installed. To do so, I followed the tutorial here, covering how to get a recent version of Ruby installed. Once installed you can check the version:

[root@localhost ~]# ruby --version
ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-linux]

The version I have installed it 2.1.8. With that done we can move on to installing Vagrant. First we need to download the .rpm package, which can be found here.  On my system, I used ‘wget’ to download the Centos Vagrant rpm file:

[root@localhost ~]# wget

Then I used the rpm tool to install the package:

[root@localhost ~]# rpm --install vagrant_1.9.5_x86_64.rpm\?_ga\=2.226527455.374667570.1497954439-963434566.1497954439

Once done, confirm Vagrant is installed by running:

[root@localhost ~]# vagrant --version
Vagrant 1.9.5

Next, the Vagrant vSphere plugin needs to be installed, to allow Vagrant to communicate with vSphere:

[root@localhost ~]# vagrant plugin install vagrant-vsphere


At this point we can move onto creating a virtual machine template in vCenter, before going back to configuring Vagrant to use it later on. For this article I decided to use a Photon OS virtual machine, as it’s a minimal install, and comes packaged with VMtools. The Photon OS .OVA can be downloaded here. You can read the Photon OS Administration Guide here, which covers a number of things, including how to configure networking. We also need to install the sudo package, as we’ll need it when prepping the VM template for use with Vagrant.

Preparing a Photon OS Template

After deploying the Photon OS VM there are a few steps needed to prepare it for use with Vagrant. First of all the user that Vagrant will use to connect to the VM needs to be created, and given a password:

[root@localhost ~]# useradd -m vagrant  
[root@localhost ~]# passwd vagrant

Next, we need to give the new Vagrant user rights to sudo without using a password. To do so, run ‘visudo’ then add the following lines to the config file:

Defaults:vagrant !requiretty  

Next, we need to create the .ssh/authorized_keys file to allow the Vagrant box to SSH into the VM without having to supply credentials:

[root@localhost ~]# mkdir -p /home/vagrant/.ssh  
[root@localhost ~]# curl -k -o /home/vagrant/.ssh/authorized_keys 

Then we need to adjust the permissions on the newly created file, so that the Vagrant user has access and is the owner:

[root@localhost ~]# chmod 0700 /home/vagrant/.ssh  
[root@localhost ~]# chmod 0600 /home/vagrant/.ssh/authorized_keys  
[root@localhost ~]# chown -R vagrant:vagrant /home/vagrant/.ssh

With that done, the prep work for the virtual machine template is complete. Shutdown the guest OS, then convert the virtual machine to a template:


Configuring Vagrant to work with vSphere

With the template ready, it’s time to go back to Vagrant to continue it’s configuration. Vagrant uses the concept of ‘boxes’ which is usually a packaged OS which Vagrant can deploy. However, when using vSphere, we already have a packaged OS in the form of the vSphere template just created. Instead we need to create a ‘dummy’ box which Vagrant can use to deploy the vSphere template. With the vSphere Vagrant plugin installed, there should be a dummy box already available. On my deployment it could be found in:


Though you may find it in a different location depending on the version you are using. Navigate to that location – you should see a metadata.json file with the following contents:

  "provider": "vsphere"

We need to zip this file to turn it into the ‘dummy’ box. To do so, run:

[root@localhost ~]# tar cvzf ./metadata.json

Next we need to create a folder to store the dummy box in. This will become the working directory for this box:

[root@localhost ~]# mkdir -p ~/vagrant_vm/example_box
[root@localhost ~]# mv ~/vagrant_vm/example_box
[root@localhost ~]# cd ~/vagrant_vm/

The last step to getting this working is to create a ‘vagrant file’. A vagrant file is what Vagrant uses to provision and start the virtual machine – it contains information about connecting to vSphere, what template to use, the name of the VM and more. To create it, use you preferred text editor and save the file as ‘Vagrantfile’ in the current location. The contents of my Vagrantfile look like this:

Vagrant.configure(2) do |config| = 'vsphere'
 config.vm.box_url = './example_box/'
 config.vm.provider 'vsphere' do |vsphere|
# vCenter or ESXi host to connect to = 'vcenter.test.local'
# The location within vCenter
vsphere.compute_resource_name = 'esxi.test.local'
# VM Resource Pool if required
# vsphere.resource_pool_name = 'VagrantVMs'
# Virtual Machine template to use
vsphere.template_name = 'PhotonTemplate'
# Provisioned Virtual Machine Name = 'PhotonVM01'
# vSphere Credentials
vsphere.user = 'administrator@vsphere.local'
vsphere.password = 'password'
# vCenter Customisation Spec to use, and IP configuration
vsphere.customization_spec_name = 'photon' 'private_network', ip: ''
# If your're using an untrusted certificate
vsphere.insecure = true end end

Most of the content above needs on explanation. One part worth covering however is the ‘ ‘private_network’, ip: ‘” setting. This will set the IP address of the provisioned virtual machine. However, in order for it to work on vSphere we need to set up a Customization Specification in vCenter and refer to it in the Vagrantfile using the ‘vsphere.customization_spec_name’ parameter. Note that we will need to specify a static IP in the customization specification, however which ever IP is used there will be overwritten by the one set in the Vagrantfile when the VM is deployed.

With that done, we’re all set to deploy a VM using Vagrant. Whilst still in the same directory as the Vagrantfile, run:

[root@localhost ~]# vagrant up -provider=vsphere

When this command is executed, you’ll see a bunch of tasks run:

Bringing machine 'default' up with 'vsphere' provider...
==> default: Calling vSphere CloneVM with the following settings:
==> default:  -- Template VM: TestDC/vm/PhotonTemplate
==> default:  -- Target VM: TestDC/vm/PhotonVM01
==> default: New virtual machine successfully cloned
==> default: Waiting for the machine to report its IP address...
    default: Timeout: 240 seconds
    default: IP:
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address:
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Host unreachable. Retrying...
    default: Warning: Host unreachable. Retrying...
    default: Warning: Host unreachable. Retrying...
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: Inserting generated public key within guest...
==> default: Machine booted and ready!

We can now check the VM is ready by establishing a session to it using the ‘vagrant ssh’ command:

[root@localhost vagrant_vm]# vagrant ssh
Last login: Wed Jun 21 14:36:33 2017 from
vagrant@PhotonVM01 [ ~ ]$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:50:56:b6:bc:81
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::250:56ff:feb6:bc81/64 Scope:Link
          RX packets:1533 errors:0 dropped:0 overruns:0 frame:0
          TX packets:425 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:120131 (120.1 KB)  TX bytes:57420 (57.4 KB)

After establishing the SSH session I ran ‘ifconfig’ to check the IP address. Note that the output shows that the IP address of the VM matches the one that was specified in the Vagrant file that was used to provision the VM.

That’s about all for this article, I’ll be posting some more on Vagrant in the near future, looking at provisioning multiple VMs. For now, we can tidy up the environment by issuing the ‘vagrant destroy’ command, which will power off and delete the provisioned VM.

Keep up to date with new posts on - Follow us on Twitter:
Be Sociable, Share!

Leave a Comment


Previous post:

Next post: