Vagrant is pretty cool, but of late I've been having real issues finding a Vagrant base box that works with VMware Fusion OOTB. My blogging workflow (used to) involve(s) using a Vagrant box with Jekyll to generate a static site on my local Mac, and then uploading to an S3 bucket. The Vagrant Jekyll boxes weren't up to scratch, so I've decided to figure out how to create my own.

This guide covers how to create the box and add it to your list of boxes, for use in specifying within a Vagrantfile. It doesn't cover Vagrant fundementals, so I assume that you'll have some basic knowledge in how it works before embarking on this magical quest.

  1. Open VMware Fusion

  2. Select “Install from disc or image” and click "Continue"

  3. Locate the ISO for the distribution you want to install, then select “Open”, and click "Continue"

  4. Unselect the checkbox for “Use Easy Install”

  5. Choose “Customize Settings"

  6. Enter a name for the VMware file (name/OSarch, i.e. wegotoeleven/trusty64) and select “Save”

  7. Customize the VM’s settings:

    • Turn on Shared Folders

    • Set memory to desired size, at least 1024MB

    • Change the Networking to "Share with my Mac" (aka NAT)

    • Change the disk size to 40 GB and deselect “Split into 2GB files”

    • Turn off the sound card

    • Expand "Advanced USB options" and select "Remove USB Controller"

    • Untick "Share Mac printers with Linux"

  8. Boot the VM, install the Guest OS and customize the following settings when prompted:

    • Host Name: Same as the second part of the name of the VMware file (i.e. trusty64)

    • Full Name: vagrant

    • User: vagrant

    • Password: vagrant

  9. Once setup and at the command prompt, login and change the Root Password. When asked, set to vagrant

    $ sudo passwd root		
    
  10. Update the OS with apt because updates

    $ sudo apt update && sudo apt upgrade -y
    
  11. Update the Sudoers file with the following to allow the vagrant user sudo rights without having to authenticate. Every. Damn. Time.

    $ sudo visudo &&
    
  12. Add the following lines, replacing or amending as necessary

    Defaults !requiretty
    #Defaults !visiblepw
    Defaults env_keep="SSH_AUTH_SOCK"
    vagrant ALL=NOPASSWD: ALL
    
  13. Test the above, by printing the working directory with sudo

    $ sudo pwd
    
  14. Restart the VM

    $ sudo shutdown -r now
    
  15. Make an ssh folder and set the .ssh folder's permissions

    $ mkdir ~/.ssh
    $ chmod 700 ~/.ssh
    
  16. Download Vagrant authorised keys from Github and add to the VM

    $ wget --no-check-certificate https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub -O ~/.ssh/authorized_keys
    
  17. Set permissions on the previously downloaded authorised keys file

    $ chmod 600 ~/.ssh/authorized_keys && chown -R vagrant ~/.ssh`
    
  18. Install OpenSSH (because without it this blog post is pointless)

    $ sudo apt install openssh-server -y
    
  19. Edit the SSH config file to disable password authentication and enable public key auth

    $ sudo vi /etc/ssh/sshd_config
    
  20. Add or modify the following lines

    Port 22
    PubKeyAuthentication yes
    AuthorizedKeysFile %h/.ssh/authorized_keys
    PermitEmptyPasswords no
    PasswordAuthentication no
    
  21. Restart SSH service

    $ sudo service ssh restart
    
  22. Install VMware Tools. Begin by mounting the VMware Tools by selecting Virtual Machines > Install VMware Tools from the menu bar menu

    $ sudo mkdir -p /mnt/cdrom
    $ sudo mount /dev/cdrom /mnt/cdrom
    $ tar xzvf /mnt/cdrom/VMwareTools-9.2.2-893683.tar.gz -C /tmp
    $ cd /tmp/vmware-tools-distrib/
    $ sudo ./vmware-install.pl
    
  23. Wipe the free space on the VM to stop fragmentation

    $ sudo dd if=/dev/zero of=/EMPTY bs=1M
    $ sudo rm -f /EMPTY
    
  24. Shutdown the VM

    $ sudo shutdown -h now
    
  25. Navigate to the location of your .vmwarevm file. By default, this location is "~/Virtual Machines/". Note: Any forward slashes will be translated into colons if the name of the VMware file contained a forward slash "/".

    $ cd ~"/Virtual Machines/wegotoeleven:xenial64.vmwarevm"
    
  26. Create a file named metadata.json, and enter the following contents

    $ vi metadata.json
    
    {"provider": "vmware_fusion"}
    
  27. Create a file named Vagrantfile, and enter the following contents

    $ vi Vagrantfile
    
    # -*- mode: ruby -*-
    # vi: set ft=ruby
    
    Vagrant.configure("2") do |config|
        config.vm.provider :vmware_fusion do |v, override|
            v.gui = false
        end
    end
    
  28. Next, optimize the box to reduce it’s size

    $ "/Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager" -d "Virtual Disk.vmdk"
    $ "/Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager" -k "Virtual Disk.vmdk"
    
  29. There's a setting that Vagrant says needs to be removed as it will "stop overwriting this setting in an upcoming release which may prevent proper networking setup". :shrug:. Open up the vmx file.

    $ vi wegotoeleven:xenial64.vmx
    
  30. Delete the line ethernet0.pcislotnumber = "32" and save.

  31. Compress and package el Vagrant box

    $ tar cvzf package.box ./*
    
  32. Finally, Add the box to your Vagrant environment. Kind of important.

    $ vagrant box add wegotoeleven/xenial64 package.box
    
  33. Go party.

Yeah, I said 30 steps. Nevermind, eh?

Much love goes out to these guys whose blog posts helped me write mine:
https://www.skoblenick.com/vagrant/creating-a-custom-box-from-scratch/
https://blog.engineyard.com/2014/building-a-vagrant-box