diff --git a/.gitignore b/.gitignore
index 11b40d7..cf50ede 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,9 @@
 .DS_Store
-.vagrant/
-www/*
+.vagrant
+.nfs
+docroot/*
 sites/*
 env/*
 manifests/site.pp
-Vagrantfile
+config/config.json
+
diff --git a/INSTALL.txt b/INSTALL.txt
index 5ab719f..f6e2653 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -12,9 +12,9 @@ SYSTEM REQUIREMENTS
 
 Undine requires:
 
-- 1GB RAM (to be dedicated to the virtual machine)
-- VirtualBox 4.2.0 (or greater)
-- Vagrant 1.3.5 (or greater)
+- 1GB RAM (to be dedicated to the virtual machine if on Windows)
+- VirtualBox 4.3.0 (or greater)
+- Vagrant 1.5 (or greater)
 - A stable Internet connection during provisioning
 
 INSTALLATION
@@ -24,65 +24,66 @@ INSTALLATION
 
 2. Download and extract Undine.
 
-3. Install the lucid32 base box for Vagrant.
+3. Install the precise32 base box for Vagrant.
 
 Undine uses a base box (base VM) of Ubuntu Lucid as a foundation, before
 performing additional configuration through the Puppet standalone. This base box
 is installed using the following command:
 
-  vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
+  `vagrant box add precise32 http://files.vagrantup.com/precise32.box`
 
-4. Choose whether or not to use NFS to share the www directory, and copy the
-appropriate file to Vagrantfile in the Undine root.
+If you have local copy of precise32.
 
-Much like copying settings.default.php to settings.php, Vagrant has its own
-settings file called "Vagrantfile" which lives in Undine's root. However, unlike
-Drupal, you are given the choice between two default configurations.
+  `vagrant box add precise32 /path/to/precise32.box`
 
-By default, Vagrant will handle shared directories (such as www on the host and
-/var/www on the VM) using VirtualBox, which is known to be non-performant for
+4. Choose whether or not to use NFS to share the www directory. You can set the
+value of `nfs` to `true` if you want to use NFS in `conf/config.json`.
+
+By default, Vagrant will handle shared directories (such as `docroot` on the host and
+`/var/www` on the VM) using VirtualBox, which is known to be non-performant for
 large sets of files. However, Undine comes with a default configuration that
 uses NFS instead, which may vastly improve your experience when accessing your
 sites in the browser.
 
-In order to use NFS, you must first install the packages nfs-kernel-server,
-nfs-common and portmap on your host system. Undine takes care of configuring the
-VM for you. You may then copy Vagrantfile.nfs to Vagrantfile and continue with
-the installation.
+In order to use NFS, you must first install the packages `nfs-kernel-server`,
+`nfs-common` and `portmap` on your host system. Undine takes care of configuring the
+VM for you.
+
+Those who cannot or do not wish to use NFS should set the value of `nfs` to
+`false` in `conf/config.json` and use VirtualBox shared directories as normal.
 
-Those who cannot or do not wish to use NFS may still copy Vagrantfile.no-nfs to
-Vagrantfile and use VirtualBox shared directories as normal.
+5. Copy `./conf/default.config.json` to `./conf/config.json` and make any
+necessary changes.
 
-5. Copy ./manifests/default.site.pp to site.pp and make any necessary changes.
+6. Copy `./manifests/default.site.pp` to `site.pp` and make any necessary changes.
 
-The site.pp file (now located in the manifests directory of your installation
+The `site.pp` file (now located in the manifests directory of your installation
 of Undine) is responsible for including all of the Puppet modules necessary
 for Undine to run. This includes any changes to your environment or Drupal sites
-you have declared: each will require an "include" entry in this file. 
+you have declared: each will require an `include` entry in this file.
 
-Please see
-the documentation for "Declaring a Drupal site" and "Overrding Undine's default
-configuration" for more information.
+Please see the documentation for `Declaring a Drupal site` and `Overrding
+Undine's default configuration` for more information.
 
-6. Set up your VM using Vagrant.
+7. Set up your VM using Vagrant.
 
 To set up your virtual machine using Vagrant, open the terminal for your
 operating system. From your Undine directory, run the following command:
 
-  vagrant up
+  `vagrant up`
 
 This will download a Vagrant base box (compatible with VirtualBox), configure it
 according to the Vagrantfile provided, and manage provisioning using the Puppet
 manifest and modules provided (including any in the sites directory of your
-Undine install, as well as any environment configuration in the env directory). 
+Undine install, as well as any environment configuration in the env directory).
 
 This may take a few moments depending on the speed of your host
 and your network connnection.
 
 7. Confirm your Web server configuration.
 
-Visit http://localhost:8080 in your Web browser. You should see an "It works!"
-page served by Apache. Now, do the same using https://localhost:8443.
+Visit `http://localhost:8080` in your Web browser. You should see an "It works!"
+page served by Apache. Now, do the same using `https://localhost:8443`.
 
 Port 80 on the guest machine (managed by Undine) is being forwarded to port 8080
 on your host machine. Likewise, https traffic on port 443 is being forwarded
@@ -94,16 +95,16 @@ host machine.
 In your open terminal, from the Undine directory, use the following command to
 connect to your virtual machine:
 
-  vagrant ssh
+  `vagrant ssh`
 
 This aptly-named command will allow you to connect to your VM via SSH. The motd
 when you log in will provide a few reminders about how your environment is
 configured by default.
 
-From here, you may work on the VM as though it were any other remote server, 
-with one notable exception: the /var/www directory of the VM is shared with the
+From here, you may work on the VM as though it were any other remote server,
+with one notable exception: the `/var/www` directory of the VM is shared with the
 www directory of your Undine installation on the host. This means that you may
-use your IDE of choice on your host, and point it to /path/to/undine/www. Your
+use your IDE of choice on your host, and point it to `/path/to/undine/docroot`. Your
 changes will be reflected on both the host and the guest VM.
 
 DECLARING A NEW DRUPAL SITE
@@ -121,14 +122,16 @@ necessary to use this feature.
 1. Create the directory for your site configuration.
 
 Within the sites directory of your Undine installation, create a directory with
-the following structure, where "mysite" is the name of your site:
+the following structure, where `mysite` is the name of your site:
 
+```
 /path/to/undine/sites/
 +--mysite/
    +--manifests
+```
 
-To recap, you will create a "mysite" directory in Undine's "sites" directory,
-with subdirectories called "manifests" and "files."
+To recap, you will create a `mysite` directory in Undine's `sites` directory,
+with subdirectories called `manifests` and `files`.
 
 2. Create the init.pp for your site configuration.
 
@@ -144,9 +147,10 @@ Your directory structure will now look like the following:
 
 3. Configure your site using init.pp.
 
-Copy /examples/sites_example for inspiration and additional details. In
+Copy `/examples/sites_example` for inspiration and additional details. In
 brief, the init.pp file for each site will contain the following:
 
+```
   * A "class mysite { }" block for all of your config.
   * The line "require undine". This is necessary to invoke Undine's features.
   * An "undine::drupal_instance { }" block to declare the Drupal site, in the
@@ -159,6 +163,7 @@ brief, the init.pp file for each site will contain the following:
     db_user      => 'mysite_db_user',
     db_pass      => 'mysite_db_pass',
   }
+```
 
 You will note that this block (a "resource" in Puppet parlance) simply accepts
 a series of key-value pairs that define the Drupal instance, to be installed in
@@ -171,7 +176,7 @@ fields. Review the documentation of undine::drupal_instance for more details.
 In the manifests directory of your Undine installation (not your defined site),
 add the following to the end of the site.pp file:
 
-  include mysite
+  `include mysite`
 
 This tells Undine to include your site when building out the virtual machine.
 
@@ -181,7 +186,7 @@ If you didn't already run "vagrant up", doing so now will create and install you
 Drupal site as you've defined it. If you have, you'll need to run the following
 command from the Undine directory in your terminal:
 
-  vagrant provision
+  `vagrant provision`
 
 Note that this will reset _all_ configuration to the defaults declared in Undine,
 not just those in your sites directory.
@@ -219,10 +224,12 @@ manifests directory. Create this text file now.
 
 Your directory structure will now look like the following:
 
+```
 /path/to/undine/sites/
 +--myenv/
    +--manifests
       +--init.pp
+```
 
 3. Configure your environment using init.pp.
 
@@ -235,7 +242,7 @@ containing all of your configuration.
 In the manifests directory of your Undine installation (not your environment),
 add the following to the end of the site.pp file:
 
-  include myenv
+  `include myenv`
 
 This tells Undine to include your config when building out the virtual machine.
 
@@ -245,7 +252,7 @@ If you didn't already run "vagrant up", doing so now will create and install you
 environment as you've defined it. If you have, you'll need to run the following
 command from the Undine directory in your terminal:
 
-  vagrant provision
+  `vagrant provision`
 
 Note that this will reset _all_ configuration to the defaults declared in Undine,
 not just those in your env directory.
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..3ef7c03
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,113 @@
+# -*- 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|
+  host = RbConfig::CONFIG['host_os']
+
+  # All Vagrant configuration is done here. The most common configuration
+  # options are documented and commented below. For a complete reference,
+  # please see the online documentation at vagrantup.com.
+
+  # Load config JSON
+  vm_config_path = File.expand_path(File.dirname(__FILE__)) + "/conf/config.json"
+  vm_config = JSON.parse(File.read(vm_config_path))
+
+  # Every Vagrant virtual environment requires a box to build off of.
+  config.vm.box = vm_config["name"]
+
+  # The url from where the 'config.vm.box' box will be fetched if it
+  # doesn't already exist on the user's system.
+  config.vm.box_url = vm_config["box_url"]
+
+  # Create a forwarded port mapping which allows access to a specific port
+  # within the machine from a port on the host machine. In the example below,
+  # accessing "localhost:8080" will access port 80 on the guest machine.
+  config.vm.network :forwarded_port, guest: vm_config["ports"]["http_guest_varnish"],
+    host: vm_config["ports"]["http_host_varnish"]
+  config.vm.network :forwarded_port, guest: vm_config["ports"]["https_guest"],
+    host: vm_config["ports"]["https_host"]
+  config.vm.network :forwarded_port, guest: vm_config["ports"]["http_guest_apache"],
+    host: vm_config["ports"]["http_host_apache"]
+
+  # Create a private network, which allows host-only access to the machine
+  # using a specific IP.
+  config.vm.network :private_network, ip: vm_config["ip"]
+
+  # VM hostname.
+  config.hostsupdater.remove_on_suspend = true
+  config.vm.hostname = vm_config["hostname"]
+
+  # Local Machine Hosts
+  #
+  # If the Vagrant plugin hostsupdater (https://github.com/cogitatio/vagrant-hostsupdater) is
+  # installed, the following will automatically configure your local machine's hosts file to
+  # be aware of the domains specified below. Watch the provisioning script as you may be
+  # required to enter a password for Vagrant to access your hosts file.
+  if defined? VagrantPlugins::HostsUpdater
+    # Capture the paths to all hostname
+    if !vm_config['aliases'].empty?
+      config.hostsupdater.aliases = vm_config['aliases'].values
+    end
+  end
+
+  # If true, then any SSH connections made will enable agent forwarding.
+  # Default value: false
+  config.ssh.forward_agent = true
+
+  # 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.
+  if vm_config["nfs"] == true
+    # Set no_root_squash to prevent NFS permissions errors on Linux during
+    # provisioning, and maproot=0:0 to correctly map the guest root user.
+    if (/darwin/ =~ host) != nil
+      config.vm.synced_folder vm_config["synced_folder"]["host_path"],
+        vm_config["synced_folder"]["guest_path"],
+        type: "nfs", :bsd__nfs_options => ["maproot=0:0"]
+    else
+      config.vm.synced_folder vm_config["synced_folder"]["host_path"],
+        vm_config["synced_folder"]["guest_path"],
+        type: "nfs", :linux__nfs_options => ["no_root_squash"]
+    end
+  else
+    config.vm.synced_folder vm_config["synced_folder"]["host_path"],
+      vm_config["synced_folder"]["guest_path"]
+  end
+
+  # Provider-specific configuration so you can fine-tune various
+  # backing providers for Vagrant. These expose provider-specific options.
+
+  config.vm.provider :virtualbox do |vb|
+    # Don't boot with headless mode
+    vb.gui = false
+    vb.name = vm_config['vm_name']
+
+    # Give VM 1/4 system memory & access to all cpu cores on the host
+    if host =~ /darwin/
+      cpus = `sysctl -n hw.ncpu`.to_i
+      # sysctl returns Bytes and we need to convert to MB
+      mem = `sysctl -n hw.memsize`.to_i / 1024 / 1024 / 4
+    elsif host =~ /linux/
+      cpus = `nproc`.to_i
+      # meminfo shows KB and we need to convert to MB
+      mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024 / 4
+    else # sorry Windows folks, I can't help you
+      cpus = 2
+      mem = 1024
+    end
+
+    vb.customize ["modifyvm", :id, "--memory", mem]
+    vb.customize ["modifyvm", :id, "--cpus", cpus]
+  end
+
+  config.vm.provision :puppet, :facter => { "host_uid" => Process.uid, "host_gid" => Process.gid } do |puppet|
+    puppet.manifests_path = "manifests"
+    puppet.manifest_file  = "site.pp"
+    puppet.module_path = ["modules", "sites", "env"]
+    # puppet.options = "--graph"
+  end
+end
diff --git a/Vagrantfile.nfs b/Vagrantfile.nfs
deleted file mode 100644
index 61c0660..0000000
--- a/Vagrantfile.nfs
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- 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|
-  # All Vagrant configuration is done here. The most common configuration
-  # options are documented and commented below. For a complete reference,
-  # please see the online documentation at vagrantup.com.
-
-  # Every Vagrant virtual environment requires a box to build off of.
-  config.vm.box = "lucid32"
-
-  # The url from where the 'config.vm.box' box will be fetched if it
-  # doesn't already exist on the user's system.
-  # config.vm.box_url = "http://domain.com/path/to/above.box"
-
-  # Create a forwarded port mapping which allows access to a specific port
-  # within the machine from a port on the host machine. In the example below,
-  # accessing "localhost:8080" will access port 80 on the guest machine.
-  config.vm.network :forwarded_port, guest: 80, host: 8080
-  config.vm.network :forwarded_port, guest: 443, host: 8443
-
-  # Create a private network, which allows host-only access to the machine
-  # using a specific IP.
-  config.vm.network :private_network, ip: "10.11.12.13"
-
-  # Create a public network, which generally matched to bridged network.
-  # Bridged networks make the machine appear as another physical device on
-  # your network.
-  # config.vm.network :public_network
-
-  # If true, then any SSH connections made will enable agent forwarding.
-  # Default value: false
-  config.ssh.forward_agent = true
-
-  # 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.
-  #
-  # Set no_root_squash to prevent NFS permissions errors on Linux during
-  # provisioning, and maproot=0:0 to correctly map the guest root user.
-  if (/darwin/ =~ RUBY_PLATFORM) != nil
-    config.vm.synced_folder "./www", "/var/www", type: "nfs", :bsd__nfs_options => ["maproot=0:0"]
-  else
-    config.vm.synced_folder "./www", "/var/www", type: "nfs", :linux__nfs_options => ["no_root_squash"]
-  end
-
-  # Provider-specific configuration so you can fine-tune various
-  # backing providers for Vagrant. These expose provider-specific options.
-  
-  # TODO: Revert before commit!
-  config.vm.provider :virtualbox do |vb|
-    vb.customize ["modifyvm", :id, "--memory", "1024"]
-  end
-
-  # View the documentation for the provider you're using for more
-  # information on available options.
-
-  # Enable provisioning with Puppet stand alone.  Puppet manifests
-  # are contained in a directory path relative to this Vagrantfile.
-  # You will need to create the manifests directory and a manifest in
-  # the file lucid32.pp in the manifests_path directory.
-  #
-  # An example Puppet manifest to provision the message of the day:
-  #
-  # # group { "puppet":
-  # #   ensure => "present",
-  # # }
-  # #
-  # # File { owner => 0, group => 0, mode => 0644 }
-  # #
-  # # file { '/etc/motd':
-  # #   content => "Welcome to your Vagrant-built virtual machine!
-  # #               Managed by Puppet.\n"
-  # # }
-  #
-  config.vm.provision :puppet, :facter => { "host_uid" => Process.uid, "host_gid" => Process.gid } do |puppet|
-    puppet.manifests_path = "manifests"
-    puppet.manifest_file  = "site.pp"
-    puppet.module_path = ["modules", "sites", "env"]
-#    puppet.options = "--graph"
-  end
-
-  # Enable provisioning with chef solo, specifying a cookbooks path, roles
-  # path, and data_bags path (all relative to this Vagrantfile), and adding
-  # some recipes and/or roles.
-  #
-  # config.vm.provision :chef_solo do |chef|
-  #   chef.cookbooks_path = "../my-recipes/cookbooks"
-  #   chef.roles_path = "../my-recipes/roles"
-  #   chef.data_bags_path = "../my-recipes/data_bags"
-  #   chef.add_recipe "mysql"
-  #   chef.add_role "web"
-  #
-  #   # You may also specify custom JSON attributes:
-  #   chef.json = { :mysql_password => "foo" }
-  # end
-
-  # Enable provisioning with chef server, specifying the chef server URL,
-  # and the path to the validation key (relative to this Vagrantfile).
-  #
-  # The Opscode Platform uses HTTPS. Substitute your organization for
-  # ORGNAME in the URL and validation key.
-  #
-  # If you have your own Chef Server, use the appropriate URL, which may be
-  # HTTP instead of HTTPS depending on your configuration. Also change the
-  # validation key to validation.pem.
-  #
-  # config.vm.provision :chef_client do |chef|
-  #   chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
-  #   chef.validation_key_path = "ORGNAME-validator.pem"
-  # end
-  #
-  # If you're using the Opscode platform, your validator client is
-  # ORGNAME-validator, replacing ORGNAME with your organization name.
-  #
-  # If you have your own Chef Server, the default validation client name is
-  # chef-validator, unless you changed the configuration.
-  #
-  #   chef.validation_client_name = "ORGNAME-validator"
-end
diff --git a/Vagrantfile.no-nfs b/Vagrantfile.no-nfs
deleted file mode 100644
index 31323ce..0000000
--- a/Vagrantfile.no-nfs
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- 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|
-  # All Vagrant configuration is done here. The most common configuration
-  # options are documented and commented below. For a complete reference,
-  # please see the online documentation at vagrantup.com.
-
-  # Every Vagrant virtual environment requires a box to build off of.
-  config.vm.box = "lucid32"
-
-  # The url from where the 'config.vm.box' box will be fetched if it
-  # doesn't already exist on the user's system.
-  # config.vm.box_url = "http://domain.com/path/to/above.box"
-
-  # Create a forwarded port mapping which allows access to a specific port
-  # within the machine from a port on the host machine. In the example below,
-  # accessing "localhost:8080" will access port 80 on the guest machine.
-  config.vm.network :forwarded_port, guest: 80, host: 8080
-  config.vm.network :forwarded_port, guest: 443, host: 8443
-
-  # Create a private network, which allows host-only access to the machine
-  # using a specific IP.
-  # config.vm.network :private_network, ip: "192.168.33.10"
-
-  # Create a public network, which generally matched to bridged network.
-  # Bridged networks make the machine appear as another physical device on
-  # your network.
-  # config.vm.network :public_network
-
-  # If true, then any SSH connections made will enable agent forwarding.
-  # Default value: false
-  config.ssh.forward_agent = true
-
-  # 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 "./www", "/var/www"
-
-  # Provider-specific configuration so you can fine-tune various
-  # backing providers for Vagrant. These expose provider-specific options.
-  
-  # TODO: Revert before commit!
-  config.vm.provider :virtualbox do |vb|
-    vb.customize ["modifyvm", :id, "--memory", "1024"]
-  end
-
-  # View the documentation for the provider you're using for more
-  # information on available options.
-
-  # Enable provisioning with Puppet stand alone.  Puppet manifests
-  # are contained in a directory path relative to this Vagrantfile.
-  # You will need to create the manifests directory and a manifest in
-  # the file lucid32.pp in the manifests_path directory.
-  #
-  # An example Puppet manifest to provision the message of the day:
-  #
-  # # group { "puppet":
-  # #   ensure => "present",
-  # # }
-  # #
-  # # File { owner => 0, group => 0, mode => 0644 }
-  # #
-  # # file { '/etc/motd':
-  # #   content => "Welcome to your Vagrant-built virtual machine!
-  # #               Managed by Puppet.\n"
-  # # }
-  #
-  config.vm.provision :puppet, :facter => { "host_uid" => Process.uid, "host_gid" => Process.gid } do |puppet|
-    puppet.manifests_path = "manifests"
-    puppet.manifest_file  = "site.pp"
-    puppet.module_path = ["modules", "sites", "env"]
-#    puppet.options = "--graph"
-  end
-
-  # Enable provisioning with chef solo, specifying a cookbooks path, roles
-  # path, and data_bags path (all relative to this Vagrantfile), and adding
-  # some recipes and/or roles.
-  #
-  # config.vm.provision :chef_solo do |chef|
-  #   chef.cookbooks_path = "../my-recipes/cookbooks"
-  #   chef.roles_path = "../my-recipes/roles"
-  #   chef.data_bags_path = "../my-recipes/data_bags"
-  #   chef.add_recipe "mysql"
-  #   chef.add_role "web"
-  #
-  #   # You may also specify custom JSON attributes:
-  #   chef.json = { :mysql_password => "foo" }
-  # end
-
-  # Enable provisioning with chef server, specifying the chef server URL,
-  # and the path to the validation key (relative to this Vagrantfile).
-  #
-  # The Opscode Platform uses HTTPS. Substitute your organization for
-  # ORGNAME in the URL and validation key.
-  #
-  # If you have your own Chef Server, use the appropriate URL, which may be
-  # HTTP instead of HTTPS depending on your configuration. Also change the
-  # validation key to validation.pem.
-  #
-  # config.vm.provision :chef_client do |chef|
-  #   chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
-  #   chef.validation_key_path = "ORGNAME-validator.pem"
-  # end
-  #
-  # If you're using the Opscode platform, your validator client is
-  # ORGNAME-validator, replacing ORGNAME with your organization name.
-  #
-  # If you have your own Chef Server, the default validation client name is
-  # chef-validator, unless you changed the configuration.
-  #
-  #   chef.validation_client_name = "ORGNAME-validator"
-end
diff --git a/conf/default.config.json b/conf/default.config.json
new file mode 100644
index 0000000..d734a1d
--- /dev/null
+++ b/conf/default.config.json
@@ -0,0 +1,27 @@
+{
+  "name": "precise32",
+  "box_url": "http://files.vagrantup.com/precise32.box",
+  "hostname": "my-hostname",
+  "aliases": {
+    // The key is used as a drush alias
+    "fox": "local.domain.com"
+  },
+  "ip": "192.168.44.45",
+  "synced_folder": {
+    "host_path": "./docroot",
+    "guest_path": "/var/www"
+  },
+  "vm_gui": false,
+  "vm_name": "acquia-drupal-platform",
+  "ports": {
+    "http_host_varnish": 8080,
+    "http_guest_varnish": 80,
+    "https_host": 8443,
+    "https_guest": 443,
+    "http_guest_apache": 1000,
+    "http_host_apache": 10000
+  },
+  "memory": 1024,
+  // Set to false if your system don't support NFS
+  "nfs": false
+}
diff --git a/docroot/README b/docroot/README
new file mode 100644
index 0000000..716babb
--- /dev/null
+++ b/docroot/README
@@ -0,0 +1,7 @@
+DO NOT DELETE THIS DIRECTORY.
+
+This directory is used by Undine to support a shared directory between
+the Undine VM and the host OS. This makes it possible to modify files
+in your IDE of choice on the host OS while serving them via Undine.
+
+For more information, please review the documentation.
diff --git a/modules/undine/manifests/init.pp b/modules/undine/manifests/init.pp
index ea303de..afb53b4 100644
--- a/modules/undine/manifests/init.pp
+++ b/modules/undine/manifests/init.pp
@@ -7,16 +7,16 @@
 # === Examples
 #
 # The primary use of the Undine class is to encapuslate basic provisioning for
-# the VM. It is intended to be declared in Puppet modules in the ./sites 
+# the VM. It is intended to be declared in Puppet modules in the ./sites
 # directory using the require syntax, typically followed by one or more
 # undine::drupal_instance resources.
-# 
+#
 #   require undine
 #   undine::drupal_instance { "mysite":
 #     ...
 #   }
 #
-class undine { 
+class undine {
   require undine_php
   require undine_git
   require undine_ssh
@@ -26,6 +26,7 @@ class undine {
   require undine_drush
   require undine_xhprof
   require undine_xdebug
+  require undine_varnish
   require undine_sendmail
 
   file { "/etc/motd":
diff --git a/modules/undine_apache/files/apache2.conf b/modules/undine_apache/files/apache2.conf
index 0f7fff9..34ae86c 100644
--- a/modules/undine_apache/files/apache2.conf
+++ b/modules/undine_apache/files/apache2.conf
@@ -8,7 +8,7 @@
 #
 # Do NOT simply read the instructions in here without understanding
 # what they do.  They're here only as hints or reminders.  If you are unsure
-# consult the online docs. You have been warned.  
+# consult the online docs. You have been warned.
 #
 # The configuration directives are grouped into three basic sections:
 #  1. Directives that control the operation of the Apache server process as a
@@ -91,7 +91,7 @@ KeepAliveTimeout 15
 
 ##
 ## Server-Pool Size Regulation (MPM specific)
-## 
+##
 
 # prefork MPM
 # StartServers: number of server processes to start
@@ -117,7 +117,7 @@ KeepAliveTimeout 15
 <IfModule mpm_worker_module>
     StartServers          2
     MinSpareThreads      25
-    MaxSpareThreads      75 
+    MaxSpareThreads      75
     ThreadLimit          64
     ThreadsPerChild      25
     MaxClients          150
@@ -135,7 +135,7 @@ KeepAliveTimeout 15
     StartServers          2
     MaxClients          150
     MinSpareThreads      25
-    MaxSpareThreads      75 
+    MaxSpareThreads      75
     ThreadLimit          64
     ThreadsPerChild      25
     MaxRequestsPerChild   0
@@ -154,8 +154,8 @@ Group ${APACHE_RUN_GROUP}
 AccessFileName .htaccess
 
 #
-# The following lines prevent .htaccess and .htpasswd files from being 
-# viewed by Web clients. 
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
 #
 <Files ~ "^\.ht">
     Order allow,deny
diff --git a/modules/undine_apache/files/default b/modules/undine_apache/files/default
index 11161f6..48a9234 100644
--- a/modules/undine_apache/files/default
+++ b/modules/undine_apache/files/default
@@ -1,33 +1,33 @@
-<VirtualHost *:80>
-	ServerAdmin webmaster@localhost
+<VirtualHost *:1000>
+  ServerAdmin webmaster@localhost
 
-	DocumentRoot /var/www
-	<Directory />
-		Options FollowSymLinks
-		AllowOverride None
-	</Directory>
-	<Directory /var/www/>
-		Options Indexes FollowSymLinks MultiViews
-		AllowOverride All
-		Order allow,deny
-		allow from all
-	</Directory>
+  DocumentRoot /var/www
+  <Directory />
+    Options FollowSymLinks
+    AllowOverride None
+  </Directory>
+  <Directory /var/www/>
+    Options Indexes FollowSymLinks MultiViews
+    AllowOverride All
+    Order allow,deny
+    allow from all
+  </Directory>
 
-	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
-	<Directory "/usr/lib/cgi-bin">
-		AllowOverride None
-		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
-		Order allow,deny
-		Allow from all
-	</Directory>
+  ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
+  <Directory "/usr/lib/cgi-bin">
+    AllowOverride None
+    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
+    Order allow,deny
+    Allow from all
+  </Directory>
 
-	ErrorLog /var/log/apache2/error.log
+  ErrorLog /var/log/apache2/error.log
 
-	# Possible values include: debug, info, notice, warn, error, crit,
-	# alert, emerg.
-	LogLevel warn
+  # Possible values include: debug, info, notice, warn, error, crit,
+  # alert, emerg.
+  LogLevel warn
 
-	CustomLog /var/log/apache2/access.log combined
+  CustomLog /var/log/apache2/access.log combined
 
     Alias /doc/ "/usr/share/doc/"
     <Directory "/usr/share/doc/">
diff --git a/modules/undine_apache/files/envvars b/modules/undine_apache/files/envvars
index e087b55..27d4e77 100644
--- a/modules/undine_apache/files/envvars
+++ b/modules/undine_apache/files/envvars
@@ -1,11 +1,20 @@
 # envvars - default environment variables for apache2ctl
 
+# for supporting multiple apache2 instances
+if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
+  SUFFIX="-${APACHE_CONFDIR##/etc/apache2-}"
+else
+  SUFFIX=
+fi
+
 # Since there is no sane way to get the parsed apache2 config in scripts, some
 # settings are defined via environment variables and then used in apache2ctl,
 # /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
 export APACHE_RUN_USER=vagrant
 export APACHE_RUN_GROUP=vagrant
 export APACHE_PID_FILE=/var/run/apache2.pid
+# Only /var/log/apache2 is handled by /etc/logrotate.d/apache2.
+export APACHE_LOG_DIR=/var/log/apache2$SUFFIX
 
 ## The locale used by some modules like mod_dav
 export LANG=C
diff --git a/modules/undine_apache/files/httpd.conf b/modules/undine_apache/files/httpd.conf
new file mode 100644
index 0000000..e69de29
diff --git a/modules/undine_apache/files/ports.conf b/modules/undine_apache/files/ports.conf
index 34456f2..30a92d7 100644
--- a/modules/undine_apache/files/ports.conf
+++ b/modules/undine_apache/files/ports.conf
@@ -5,8 +5,8 @@
 # Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and
 # README.Debian.gz
 
-NameVirtualHost *:80
-Listen 80
+NameVirtualHost *:1000
+Listen 1000
 
 <IfModule mod_ssl.c>
     # If you add NameVirtualHost *:443 here, you will also have to change
diff --git a/modules/undine_apache/lib/puppet/parser/functions/get_server_filename.rb b/modules/undine_apache/lib/puppet/parser/functions/get_server_filename.rb
index a03f652..75d640d 100644
--- a/modules/undine_apache/lib/puppet/parser/functions/get_server_filename.rb
+++ b/modules/undine_apache/lib/puppet/parser/functions/get_server_filename.rb
@@ -16,7 +16,7 @@
 #
 # Translates "my.localhost.test" to "my-localhost-test"
 #
-#   $name = get_project_name('my.localhost.test')
+# $name = get_project_name('my.localhost.test')
 #
 module Puppet::Parser::Functions
   newfunction(:get_server_filename, :type => :rvalue) do |args|
diff --git a/modules/undine_apache/manifests/httpd_mod.pp b/modules/undine_apache/manifests/httpd_mod.pp
index 55f49f3..0c91de1 100644
--- a/modules/undine_apache/manifests/httpd_mod.pp
+++ b/modules/undine_apache/manifests/httpd_mod.pp
@@ -26,16 +26,16 @@
 #
 # === Examples
 #
-#   undine_apache::http_mod { 'mod_rewrite':
-#     mod_name => 'rewrite',
-#     load_source => 'puppet:///modules/my_rw_module/rewrite.load',
-#   }
+# undine_apache::http_mod { 'mod_rewrite':
+#   mod_name => 'rewrite',
+#   load_source => 'puppet:///modules/my_rw_module/rewrite.load',
+# }
 #
-#   undine_apache::http_mod { 'mod_ssl':
-#     mod_name => 'ssl',
-#     load_source => 'puppet:///modules/my_ssl_module/ssl.load',
-#     conf_source => 'puppet:///modules/my_ssl_module/ssl.conf',
-#   }
+# undine_apache::http_mod { 'mod_ssl':
+#   mod_name => 'ssl',
+#   load_source => 'puppet:///modules/my_ssl_module/ssl.load',
+#   conf_source => 'puppet:///modules/my_ssl_module/ssl.conf',
+# }
 #
 define undine_apache::httpd_mod (
   $mod_name,
diff --git a/modules/undine_apache/manifests/init.pp b/modules/undine_apache/manifests/init.pp
index 40240ee..0876516 100644
--- a/modules/undine_apache/manifests/init.pp
+++ b/modules/undine_apache/manifests/init.pp
@@ -5,25 +5,26 @@
 # includes core apache configuration, ports configuration, default site
 # configuration, and Apache module installation and configuration.
 #
-# It should not be necessary to declare this class directly, as it will be 
+# It should not be necessary to declare this class directly, as it will be
 # declared automatically by the undine class, which all Undine sites should use.
 #
 # Integration of PHP with Apache is provided in undine_apache_php.
-# 
+#
 class undine_apache {
 
-  exec { "apache-update-sources-file":
-    command => '/usr/bin/apt-get update',
-  }
-
   # Install package and dependencies.
   package { 'apache2':
     ensure => installed,
-    require => Exec['apache-update-sources-file'],
   }
 
   # Manage core configuration files.
 
+  file { '/etc/apache2/httpd.conf':
+    path => '/etc/apache2/httpd.conf',
+    ensure => file,
+    require => Package['apache2'],
+    source => 'puppet:///modules/undine_apache/httpd.conf',
+  }
   file { '/etc/apache2/apache2.conf':
     path => '/etc/apache2/apache2.conf',
     ensure => file,
@@ -75,7 +76,7 @@ class undine_apache {
     ensure => link,
     target => '/etc/apache2/sites-available/default',
     require => File['/etc/apache2/sites-available/default'],
-  }    
+  }
   file { '/etc/apache2/sites-enabled/000-default-ssl':
     path => '/etc/apache2/sites-enabled/000-default-ssl',
     ensure => link,
diff --git a/modules/undine_apache/manifests/misc_conf_file.pp b/modules/undine_apache/manifests/misc_conf_file.pp
index c5e3af8..d83cd58 100644
--- a/modules/undine_apache/manifests/misc_conf_file.pp
+++ b/modules/undine_apache/manifests/misc_conf_file.pp
@@ -25,9 +25,9 @@
 #
 # === Examples
 #
-#   undine_apache::misc_conf_file { '/etc/php/php.ini':
-#     source => 'puppet:///modules/my_php_module/php.ini',
-#   }
+# undine_apache::misc_conf_file { '/etc/php/php.ini':
+#   source => 'puppet:///modules/my_php_module/php.ini',
+# }
 #
 define undine_apache::misc_conf_file (
   $content = undef,
diff --git a/modules/undine_apache/manifests/virtualhost.pp b/modules/undine_apache/manifests/virtualhost.pp
index f0c8b65..95dc11a 100644
--- a/modules/undine_apache/manifests/virtualhost.pp
+++ b/modules/undine_apache/manifests/virtualhost.pp
@@ -15,9 +15,9 @@
 #
 # === Examples
 #
-#   undine_apache::virtualhost { 'mysite.local':
-#     document_root => '/var/www/html/mydir',
-#   }
+# undine_apache::virtualhost { 'mysite.local':
+#   document_root => '/var/www/html/mydir',
+# }
 #
 define undine_apache::virtualhost(
   $document_root,
diff --git a/modules/undine_apache/templates/virtualhost.erb b/modules/undine_apache/templates/virtualhost.erb
index 3a7d0f8..934ce2c 100644
--- a/modules/undine_apache/templates/virtualhost.erb
+++ b/modules/undine_apache/templates/virtualhost.erb
@@ -1,4 +1,4 @@
-<VirtualHost *:80>
+<VirtualHost *:1000>
         ServerAdmin webmaster@localhost
         ServerName <%= @server_name %>
 
diff --git a/modules/undine_apache_php/files/apache2.conf b/modules/undine_apache_php/files/apache2.conf
index 0f7fff9..562531f 100644
--- a/modules/undine_apache_php/files/apache2.conf
+++ b/modules/undine_apache_php/files/apache2.conf
@@ -8,7 +8,7 @@
 #
 # Do NOT simply read the instructions in here without understanding
 # what they do.  They're here only as hints or reminders.  If you are unsure
-# consult the online docs. You have been warned.  
+# consult the online docs. You have been warned.
 #
 # The configuration directives are grouped into three basic sections:
 #  1. Directives that control the operation of the Apache server process as a
@@ -91,7 +91,7 @@ KeepAliveTimeout 15
 
 ##
 ## Server-Pool Size Regulation (MPM specific)
-## 
+##
 
 # prefork MPM
 # StartServers: number of server processes to start
@@ -117,7 +117,7 @@ KeepAliveTimeout 15
 <IfModule mpm_worker_module>
     StartServers          2
     MinSpareThreads      25
-    MaxSpareThreads      75 
+    MaxSpareThreads      75
     ThreadLimit          64
     ThreadsPerChild      25
     MaxClients          150
@@ -135,7 +135,7 @@ KeepAliveTimeout 15
     StartServers          2
     MaxClients          150
     MinSpareThreads      25
-    MaxSpareThreads      75 
+    MaxSpareThreads      75
     ThreadLimit          64
     ThreadsPerChild      25
     MaxRequestsPerChild   0
@@ -154,8 +154,8 @@ Group ${APACHE_RUN_GROUP}
 AccessFileName .htaccess
 
 #
-# The following lines prevent .htaccess and .htpasswd files from being 
-# viewed by Web clients. 
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
 #
 <Files ~ "^\.ht">
     Order allow,deny
@@ -205,7 +205,7 @@ Include /etc/apache2/mods-enabled/*.load
 Include /etc/apache2/mods-enabled/*.conf
 
 # Include all the user configurations:
-Include /etc/apache2/httpd.conf
+# Include /etc/apache2/httpd.conf
 
 # Include ports listing
 Include /etc/apache2/ports.conf
diff --git a/modules/undine_apache_php/files/httpd.conf b/modules/undine_apache_php/files/httpd.conf
new file mode 100644
index 0000000..e69de29
diff --git a/modules/undine_git/files/git-core-ppa-precise.list b/modules/undine_git/files/git-core-ppa-precise.list
new file mode 100644
index 0000000..aac43b2
--- /dev/null
+++ b/modules/undine_git/files/git-core-ppa-precise.list
@@ -0,0 +1 @@
+deb http://ppa.launchpad.net/git-core/ppa/ubuntu precise main
diff --git a/modules/undine_git/manifests/identity.pp b/modules/undine_git/manifests/identity.pp
index e2b0231..d6bd9f4 100644
--- a/modules/undine_git/manifests/identity.pp
+++ b/modules/undine_git/manifests/identity.pp
@@ -13,9 +13,9 @@
 #
 # === Examples
 #
-#   undine_git::identity { "Jane Smith":
-#     email => 'jsmith@example.com',
-#   }
+# undine_git::identity { "Jane Smith":
+#   email => 'jsmith@example.com',
+# }
 #
 define undine_git::identity (
   $git_name = $title,
diff --git a/modules/undine_git/manifests/init.pp b/modules/undine_git/manifests/init.pp
index b241a2e..8afa04b 100644
--- a/modules/undine_git/manifests/init.pp
+++ b/modules/undine_git/manifests/init.pp
@@ -10,8 +10,8 @@ class undine_git {
   undine_apt::ppa { "git-core/ppa":
     ppa_user => 'git-core',
     ppa_name => 'ppa',
-    source_list_d_filename => 'git-core-ppa-lucid.list',
-    source_list_d_source => 'puppet:///modules/undine_git/git-core-ppa-lucid.list',
+    source_list_d_filename => 'git-core-ppa-precise.list',
+    source_list_d_source => 'puppet:///modules/undine_git/git-core-ppa-precise.list',
   }
 
   package { "git":
diff --git a/modules/undine_git/manifests/remote.pp b/modules/undine_git/manifests/remote.pp
index 69fc0d9..f06c091 100644
--- a/modules/undine_git/manifests/remote.pp
+++ b/modules/undine_git/manifests/remote.pp
@@ -1,7 +1,7 @@
 # == Define: remote
 #
 # The remote defined type is responsible for the management of multiple remotes
-# for Git repositories managed by in Undine. 
+# for Git repositories managed by in Undine.
 #
 # The remote defined type also provides a means of authenticating via SSH using
 # a combination of agent forwarding to use your host environment's SSH keys
@@ -18,49 +18,49 @@
 # [*repo_path*]
 #   The destination path of the repository to add the remote to. This repository
 #   must already exist in the filesystem.
-# [*hostname*]
+# [*known_host_name*]
 #   Optional. The hostname of the remote to whitelist when using SSH. Must be
 #   defined along with known_host_key.
 # [*known_host_key*]
 #   Optional. The key of the remote to add to known_hosts for use with SSH. Must
-#   be defined along with hostname.
+#   be defined along with known_host_name.
 #
 # === Examples
 #
 # Usage via SSH with an associated known_host entry.
 #
-#   undine_git::remote { "example_remote":
-#     remote_uri => 'user@git.example.com:example.git',
-#     repo_path => '/var/www/example',
-#     hostname => 'git.example.com',
-#     known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
-#   }
+# undine_git::remote { "example_remote":
+#   remote_uri => 'user@git.example.com:example.git',
+#   repo_path => '/var/www/example',
+#   known_host_name => 'git.example.com',
+#   known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
+# }
 #
 define undine_git::remote (
   $remote_name = $title,
   $remote_uri,
   $repo_path,
-  $hostname = undef,
+  $known_host_name = undef,
   $known_host_key = undef,
 ) {
   require undine_git
-  
-  if ($hostname != undef and $known_host_key == undef) or ($hostname == undef and $known_host_key != undef) {
-    fail('If hostname is provided to a git remote, known_host_key must also be provided, and vice-versa.')
+
+  if ($known_host_name != undef and $known_host_key == undef) or ($known_host_name == undef and $known_host_key != undef) {
+    fail('If known_host_name is provided to a git remote, known_host_key must also be provided, and vice-versa.')
   }
 
-  if $hostname != undef and $known_host_key != undef {
+  if $known_host_name != undef and $known_host_key != undef {
     include undine_ssh
 
-    if !defined(Undine_ssh::Known_host["${hostname}"]) {
-      undine_ssh::known_host { "${hostname}":
+    if !defined(Undine_ssh::Known_host["${known_host_name}"]) {
+      undine_ssh::known_host { "${known_host_name}":
         key => $known_host_key,
       }
     }
-    
-    # Declare the relationship with chaining arrows, since we can't rely on
-    # changing the initial state of the resource itself if it already exists.
-    Undine_ssh::Known_host["${hostname}"] -> Exec["git-remote-${remote_name}-${repo_path}"]
+
+  # Declare the relationship with chaining arrows, since we can't rely on
+  # changing the initial state of the resource itself if it already exists.
+  Undine_ssh::Known_host["${known_host_name}"] -> Exec["git-remote-${remote_name}-${repo_path}"]
   }
   # Apply the remote unless it already exists.
   exec { "git-remote-${remote_name}-${repo_path}":
diff --git a/modules/undine_git/manifests/repository.pp b/modules/undine_git/manifests/repository.pp
index 904402c..7feafc2 100644
--- a/modules/undine_git/manifests/repository.pp
+++ b/modules/undine_git/manifests/repository.pp
@@ -1,7 +1,7 @@
 # == Define: repository
 #
-# The repository defined type is responsible for the management of Git 
-# repositories in Undine. 
+# The repository defined type is responsible for the management of Git
+# repositories in Undine.
 #
 # The repository defined type also provides a means of authenticating via SSH
 # using a combination of agent forwarding to use your host environment's SSH
@@ -11,104 +11,104 @@
 #
 # === Parameters
 #
-# [*path*]
-#   The destination path to be used by git clone. This path must not
+# [*directory*]
+#   The destination directory to be used by git clone. This directory must not
 #   already exist in the filesystem.
 # [*repo_uri*]
 #   Optional. The URI of the repository to clone. Defaults to the resource
 #   title.
 # [*branch*]
 #   Optional. The branch to checkout. Defaults to HEAD.
-# [*hostname*]
+# [*known_host_name*]
 #   Optional. The hostname of the repository to whitelist when using SSH. Must
 #   be defined along with known_host_key.
 # [*known_host_key*]
-#   Optional. The key of the repository to add to known_hosts for use with SSH. 
-#   Must be defined along with hostname.
+#   Optional. The key of the repository to add to known_hosts for use with SSH.
+#   Must be defined along with known_host_name.
 # [*remotes*]
 #   Optional. A hash of remotes for this repository, keyed by the name of the
 #   remote with a hash representing the remote as a value. These hash keys and
 #   values are the same as those used in undine_git::remote (with repo_path
-#   automatically populated using the value of path).
+#   automatically populated using the value of directory).
 #
 # === Examples
 #
 # Simple usage via HTTP.
 #
-#   undine_git::repository { "http://git.example.com/project/example.git":
-#     path => '/var/www/example',
-#   }
+# undine_git::repository { "http://git.example.com/project/example.git":
+#   directory => '/var/www/example',
+# }
 #
 # Usage via SSH with a defined branch and associated known_host entry. Also
 # declares an additional remote to use with the repository once cloned.
 #
-#   undine_git::repository { "ssh://user@git.example.com/project/example.git":
-#     branch => '7.x-1.x',
-#     path => '/var/www/example',
-#     hostname => 'git.example.com',
-#     known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
-#     remotes => { 
-#        "example_remote" => {
-#          remote_uri => 'user@git.example.com:example.git',
-#          hostname => 'git.example.com',
-#          known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
-#       },
+# undine_git::repository { "ssh://user@git.example.com/project/example.git":
+#   branch => '7.x-1.x',
+#   directory => '/var/www/example',
+#   known_host_name => 'git.example.com',
+#   known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
+#   remotes => {
+#      "example_remote" => {
+#        remote_uri => 'user@git.example.com:example.git',
+#        known_host_name => 'git.example.com',
+#        known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
 #     },
-#   }
+#   },
+# }
 #
 define undine_git::repository (
-  $path,
+  $directory,
   $repo_uri = $title,
   $branch = undef,
-  $hostname = undef,
+  $known_host_name = undef,
   $known_host_key = undef,
   $remotes = undef,
 ) {
   require undine_git
-  
-  if ($hostname != undef and $known_host_key == undef) or ($hostname == undef and $known_host_key != undef) {
-    fail('If hostname is provided to a git repository, known_host_key must also be provided, and vice-versa.')
+
+  if ($known_host_name != undef and $known_host_key == undef) or ($known_host_name == undef and $known_host_key != undef) {
+    fail('If known_host_name is provided to a git repository, known_host_key must also be provided, and vice-versa.')
   }
 
   if ($branch != undef) {
     $branch_flag = "--branch ${branch}"
-  }  
+  }
   else {
     $branch_flag = ''
   }
 
-  if $hostname != undef and $known_host_key != undef {
+  if $known_host_name != undef and $known_host_key != undef {
     include undine_ssh
 
-    if !defined(Undine_ssh::Known_host["${hostname}"]) {
-      undine_ssh::known_host { "${hostname}":
+    if !defined(Undine_ssh::Known_host["${known_host_name}"]) {
+      undine_ssh::known_host { "${known_host_name}":
         key => $known_host_key,
       }
     }
-    
-    # Declare the relationship with chaining arrows, since we can't rely on
-    # changing the initial state of the resource itself if it already exists.
-    Undine_ssh::Known_host["${hostname}"] -> Exec["git-clone-to-${path}"]
+
+  # Declare the relationship with chaining arrows, since we can't rely on
+  # changing the initial state of the resource itself if it already exists.
+  Undine_ssh::Known_host["${known_host_name}"] -> Exec["git-clone-to-${directory}"]
   }
-  exec { "git-clone-to-${path}":
-    unless => "/bin/ls ${path}/.git",
-    command => "/usr/bin/git clone -v ${branch_flag} ${repo_uri} ${path}",
+  exec { "git-clone-to-${directory}":
+    unless => "/bin/ls ${directory}/.git",
+    command => "/usr/bin/git clone -v ${branch_flag} ${repo_uri} ${directory}",
   }
-  exec { "git-clone-to-${path}-ownership":
-    command => "/bin/chown -R ${host_uid}:20 ${path}",
-    require => Exec["git-clone-to-${path}"],
+  exec { "git-clone-to-${directory}-ownership":
+    command => "/bin/chown -R ${host_uid}:20 ${directory}",
+    require => Exec["git-clone-to-${directory}"],
     logoutput => $logoutput,
   }
-  exec { "git-clone-to-${path}-permissions":
-    command => "/bin/chmod -R 775 ${path}",
-    require => Exec["git-clone-to-${path}-ownership"],
+  exec { "git-clone-to-${directory}-permissions":
+    command => "/bin/chmod -R 775 ${directory}",
+    require => Exec["git-clone-to-${directory}-ownership"],
     logoutput => $logoutput,
   }
-  
+
   # Set default path and dependency information for remotes.
   $defaults = {
-    'require' => Exec["git-clone-to-${path}"],
-    'repo_path' => "${path}",
+    'require' => Exec["git-clone-to-${directory}"],
+    'repo_path' => "${directory}",
   }
   create_resources(undine_git::remote, $remotes, $defaults)
 }
diff --git a/modules/undine_percona/files/percona.list b/modules/undine_percona/files/percona.list
index 6bbf50e..5c311f1 100644
--- a/modules/undine_percona/files/percona.list
+++ b/modules/undine_percona/files/percona.list
@@ -1,2 +1,2 @@
-deb http://repo.percona.com/apt lucid main
-deb-src http://repo.percona.com/apt lucid main
+deb http://repo.percona.com/apt precise main
+deb-src http://repo.percona.com/apt precise main
diff --git a/modules/undine_percona/lib/puppet/parser/functions/convert_grants_to_resources.rb b/modules/undine_percona/lib/puppet/parser/functions/convert_grants_to_resources.rb
index 24f08b8..f5f1d54 100644
--- a/modules/undine_percona/lib/puppet/parser/functions/convert_grants_to_resources.rb
+++ b/modules/undine_percona/lib/puppet/parser/functions/convert_grants_to_resources.rb
@@ -26,15 +26,15 @@
 #
 # GRANTs the CREATE, UPDATE, and DELETE permissions on my_database to my_user.
 #
-#   $grants = {
-#     'my_database' => [
-#       'CREATE',
-#       'UPDATE',
-#       'DELETE',
-#     ],
-#   }
-#   $exec_hash = convert_grants_to_resources('my_user', $grants)
-#   create_resources(exec, $exec_hash)
+# $grants = {
+#   'my_database' => [
+#     'CREATE',
+#     'UPDATE',
+#     'DELETE',
+#   ],
+# }
+# $exec_hash = convert_grants_to_resources('my_user', $grants)
+# create_resources(exec, $exec_hash)
 #
 module Puppet::Parser::Functions
   newfunction(:convert_grants_to_resources, :type => :rvalue) do |args|
diff --git a/modules/undine_percona/manifests/database.pp b/modules/undine_percona/manifests/database.pp
index 4fcba5f..248edbf 100644
--- a/modules/undine_percona/manifests/database.pp
+++ b/modules/undine_percona/manifests/database.pp
@@ -19,7 +19,7 @@
 #   exclusive with the src_ssh parameters.
 # [*src_ssh_user*]
 #   Optional. The remote ssh user to use when connecting to the database.
-# [*src_hostname*]
+# [*src_ssh_host*]
 #   Optional. The host on which the remote database resides. Must be supplied
 #   when retrieving a database from a remote host via SSH.
 # [*src_ssh_known_host_key*]
@@ -59,19 +59,19 @@
 # as remote_mysql_user:correcthorsebatterystaple. Note that the host is added to
 # known_hosts using src_ssh_known_host_key.
 #
-#   undine_percona::database { 'mysite_db':
-#     src_ssh_user => 'user',
-#     src_hostname => 'ssh.example.com',
-#     src_ssh_known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/ ...',
-#     src_db_name => 'rmdb',
-#     src_db_user => 'remote_mysql_user',
-#     src_db_pass => 'correcthorsebatterystaple',
-#   }
+# undine_percona::database { 'mysite_db':
+#   src_ssh_user => 'user',
+#   src_ssh_host => 'ssh.example.com',
+#   src_ssh_known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/ ...',
+#   src_db_name => 'rmdb',
+#   src_db_user => 'remote_mysql_user',
+#   src_db_pass => 'correcthorsebatterystaple',
+# }
 #
 define undine_percona::database (
   $db_name = $title,
   $src_ssh_user = undef,
-  $src_hostname = undef,
+  $src_ssh_host = undef,
   $src_ssh_known_host_key = undef,
   $src_db_name = undef,
   $src_db_user = undef,
@@ -110,7 +110,7 @@ define undine_percona::database (
     require => Service['mysql'],
   }
 
-  if $src_hostname != undef and $src_path != undef {
+  if $src_ssh_host != undef and $src_path != undef {
     fail('A Percona database cannot define both an SSH and a local path source.')
   }
 
@@ -124,17 +124,17 @@ define undine_percona::database (
       ],
     }
   }
-  elsif $src_hostname != undef {
-    if $src_ssh_known_host_key != undef and $src_hostname != undef {
-      if !defined(Undine_ssh::Known_host["${src_hostname}"]) {
-        undine_ssh::known_host { "${src_hostname}":
+  elsif $src_ssh_host != undef {
+    if $src_ssh_known_host_key != undef and $src_ssh_host != undef {
+      if !defined(Undine_ssh::Known_host["${src_ssh_host}"]) {
+        undine_ssh::known_host { "${src_ssh_host}":
           key => $src_ssh_known_host_key,
         }
       }
 
       # Declare the relationship with chaining arrows, since we can't rely on
       # changing the initial state of the resource itself if it already exists.
-      Undine_ssh::Known_host["${src_hostname}"] -> Exec["percona-database-${db_name}-import"]
+      Undine_ssh::Known_host["${src_ssh_host}"] -> Exec["percona-database-${db_name}-import"]
     }
 
     if $src_db_pass != undef {
@@ -144,10 +144,10 @@ define undine_percona::database (
       $src_db_pass_flag = ''
     }
 
-    if $src_hostname != undef and $src_db_name != undef and $src_db_user != undef {
+    if $src_ssh_host != undef and $src_db_name != undef and $src_db_user != undef {
       exec { "percona-database-${db_name}-import":
         onlyif => "/usr/bin/mysql -u${su_user} ${su_pass_flag} ${db_name} -e 'SHOW TABLES;' | wc -l | grep \"^0$\"",
-        command => "/usr/bin/ssh ${src_ssh_user}@${src_hostname} 'mysqldump -u${src_db_user} ${src_db_pass_flag} ${src_db_name}' | /usr/bin/mysql -u${su_user} ${su_pass_flag} -D ${db_name}",
+        command => "/usr/bin/ssh ${src_ssh_user}@${src_ssh_host} 'mysqldump -u${src_db_user} ${src_db_pass_flag} ${src_db_name}' | /usr/bin/mysql -u${su_user} ${su_pass_flag} -D ${db_name}",
         require => [
           Service['mysql'],
           Exec["percona-database-${db_name}"],
diff --git a/modules/undine_percona/manifests/misc_conf_file.pp b/modules/undine_percona/manifests/misc_conf_file.pp
index 981e043..4a71a29 100644
--- a/modules/undine_percona/manifests/misc_conf_file.pp
+++ b/modules/undine_percona/manifests/misc_conf_file.pp
@@ -20,9 +20,9 @@
 #
 # === Examples
 #
-#   undine_percona::misc_conf_file { '/etc/mysql/conf.d/override.cnf':
-#     source => 'puppet:///modules/my_percona_module/override.cnf',
-#   }
+# undine_percona::misc_conf_file { '/etc/mysql/conf.d/override.cnf':
+#   source => 'puppet:///modules/my_percona_module/override.cnf',
+# }
 #
 define undine_percona::misc_conf_file (
   $content = undef,
diff --git a/modules/undine_percona/manifests/user.pp b/modules/undine_percona/manifests/user.pp
index b7d5e79..00c4c1c 100644
--- a/modules/undine_percona/manifests/user.pp
+++ b/modules/undine_percona/manifests/user.pp
@@ -21,21 +21,18 @@
 #
 # === Examples
 #
-# Creates mysite_db_user with a password of correcthorsebatterystaple and GRANTs
-# SELECT, INSERT, UPDATE and DELETE on mysite_db. Also grants ALL to other_db.
-#
-#   undine_percona::user { 'mysite_db_user':
-#     password => 'correcthorsebatterystaple',
-#     grants => {
-#       'mysite_db' => [
-#         'SELECT', 
-#         'INSERT', 
-#         'UPDATE',
-#         'DELETE',
-#       ],
-#       'other_db' => ['ALL'],
-#     },
-#   }
+# undine_percona::user { 'mysite_db_user':
+#   password => 'correcthorsebatterystaple',
+#   grants => {
+#     'mysite_db' => [
+#       'SELECT', 
+#       'INSERT', 
+#       'UPDATE',
+#       'DELETE',
+#     ],
+#     'other_db' => ['ALL'],
+#   },
+# }
 #
 define undine_percona::user (
   $password,
diff --git a/modules/undine_php/files/aoe-php-precise.list b/modules/undine_php/files/aoe-php-precise.list
new file mode 100644
index 0000000..b34780a
--- /dev/null
+++ b/modules/undine_php/files/aoe-php-precise.list
@@ -0,0 +1,2 @@
+deb http://ppa.launchpad.net/aoe/php/ubuntu precise main
+deb-src http://ppa.launchpad.net/aoe/php/ubuntu precise main
diff --git a/modules/undine_php/manifests/init.pp b/modules/undine_php/manifests/init.pp
index 533be3f..36ae451 100644
--- a/modules/undine_php/manifests/init.pp
+++ b/modules/undine_php/manifests/init.pp
@@ -1,29 +1,29 @@
 # == Class: undine_php
 #
 # The undine_php class is responsible for the installation and configuration
-# of PHP. Installation is done via the signed packages made available on the 
-# skettler PPA.
+# of PHP. Installation is done via the signed packages made available on the
+# aoe PPA.
 #
 # It should not be necessary to declare this class directly, as it will be
 # declared automatically by the undine class, which all Undine sites should use.
 #
 class undine_php {
 
-  undine_apt::ppa { 'skettler/php':
-    ppa_user => 'skettler',
+  undine_apt::ppa { 'aoe/php':
+    ppa_user => 'aoe',
     ppa_name => 'php',
-    source_list_d_filename => 'skettler-php-lucid.list',
-    source_list_d_source => 'puppet:///modules/undine_php/skettler-php-lucid.list',
+    source_list_d_filename => 'aoe-php-precise.list',
+    source_list_d_source => 'puppet:///modules/undine_php/aoe-php-precise.list',
   }
 
   # Install PHP 5.3 package.
   package { "php53":
     ensure => installed,
-    require => Undine_apt::Ppa['skettler/php'],
+    require => Undine_apt::Ppa['aoe/php'],
   }
   package { "php53-pear":
     ensure => installed,
-    require => Undine_apt::Ppa['skettler/php'],
+    require => Undine_apt::Ppa['aoe/php'],
   }
 }
 
diff --git a/modules/undine_rsync/manifests/directory.pp b/modules/undine_rsync/manifests/directory.pp
index 6f5a870..b802e38 100644
--- a/modules/undine_rsync/manifests/directory.pp
+++ b/modules/undine_rsync/manifests/directory.pp
@@ -12,9 +12,9 @@
 #
 # === Parameters
 #
-# [*dest_path*]
+# [*dest_dir*]
 #   The destination directory on the local VM. Defaults to the resource title.
-# [*src_path*]
+# [*src_dir*]
 #   The source directory from which to rsync files. Provide src_hostname to
 #   rsync from a remote host.
 # [*src_hostname*]
@@ -28,23 +28,23 @@
 #
 # Simple local usage.
 # 
-#   undine_rsync::directory { '/path/to/dest':
-#     src_path => '/path/to/my/src',
-#   }
+# undine_rsync::directory { '/path/to/dest':
+#   src_dir => '/path/to/my/src',
+# }
 # 
 # Usage via SSH with a defined remote host and associated known_host entry.
 # 
-#   undine_rsync::directory { '/path/to/dest':
-#     src_path => '/path/to/my/remote/src',
-#     src_hostname => 'example.com',
-#     src_known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
-#     src_username => 'jsmith',
-#   }
+# undine_rsync::directory { '/path/to/dest':
+#   src_dir => '/path/to/my/remote/src',
+#   src_hostname => 'example.com',
+#   src_known_host_key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJW ...',
+#   src_username => 'jsmith',
+# }
 # 
 # 
 define undine_rsync::directory (
-  $src_path,
-  $dest_path = $title,
+  $src_dir,
+  $dest_dir = $title,
   $src_username = undef,
   $src_hostname = undef,
   $src_known_host_key = undef,
@@ -73,7 +73,7 @@ define undine_rsync::directory (
     $host = ''
   }
 
-  $exec_str = "/usr/bin/rsync --timeout=0 -rltgoDvz -e ssh ${user}${host}${src_path} ${dest_path}"
+  $exec_str = "/usr/bin/rsync --timeout=0 -rltgoDvz -e ssh ${user}${host}${src_dir} ${dest_dir}"
 
   if $src_known_host_key != undef {
     if !defined(Undine_ssh::Known_host["${src_hostname}"]) {
@@ -92,14 +92,14 @@ define undine_rsync::directory (
     require => Package['rsync'],
     logoutput => $logoutput,
   }
-  exec { "rsync-to-${dest_path}-ownership":
-    command => "/bin/chown -R ${host_uid}:20 ${dest_path}",
+  exec { "rsync-to-${dest_dir}-ownership":
+    command => "/bin/chown -R ${host_uid}:20 ${dest_dir}",
     require => Exec["${exec_str}"],
     logoutput => $logoutput,
   }
-  exec { "rsync-to-${dest_path}-permissions":
-    command => "/bin/chmod -R 775 ${dest_path}",
-    require => Exec["rsync-to-${dest_path}-ownership"],
+  exec { "rsync-to-${dest_dir}-permissions":
+    command => "/bin/chmod -R 775 ${dest_dir}",
+    require => Exec["rsync-to-${dest_dir}-ownership"],
     logoutput => $logoutput,
   }
 }
diff --git a/modules/undine_ssh/manifests/known_host.pp b/modules/undine_ssh/manifests/known_host.pp
index 1da0430..d502c00 100644
--- a/modules/undine_ssh/manifests/known_host.pp
+++ b/modules/undine_ssh/manifests/known_host.pp
@@ -21,11 +21,9 @@
 #
 # === Examples
 #
-# Create a known_host entry for git.example.com
-#
-#   undine_ssh::known_host { 'git.example.com':
-#     key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJWtxGRVCis= ...'
-#   }
+# undine_ssh::known_host { 'git.example.com':
+#   key => '|1|nddsvUkIUHNdM31TTSc+sPT57yg=|nQqEyJJthk/DTVaRmJWtxGRVCis= ...'
+# }
 #
 define undine_ssh::known_host (
   $hostname = $title,
diff --git a/modules/undine_tar/manifests/archive.pp b/modules/undine_tar/manifests/archive.pp
index 98a560f..fc591fe 100644
--- a/modules/undine_tar/manifests/archive.pp
+++ b/modules/undine_tar/manifests/archive.pp
@@ -28,18 +28,18 @@
 #
 # Simple local usage.
 # 
-#   undine_tar::archive { '/path/to/dest':
-#     src_path => '/path/to/my/src/archive.tar',
-#   }
+# undine_tar::archive { '/path/to/dest':
+#   src_path => '/path/to/my/src/archive.tar',
+# }
 # 
 # Usage via wget via basic auth, with gzip support.
 # 
-#   undine_tar::archive { '/path/to/dest':
-#     src_path => 'http://example.com/path/to/my/archive.tar.gz',
-#     src_username => 'jsmith',
-#     src_password => 'correcthorsebatterystaple',
-#     gzip => true,
-#   }
+# undine_tar::archive { '/path/to/dest':
+#   src_path => 'http://example.com/path/to/my/archive.tar.gz',
+#   src_username => 'jsmith',
+#   src_password => 'correcthorsebatterystaple',
+#   gzip => true,
+# }
 #
 define undine_tar::archive (
   $path = $title,
diff --git a/modules/undine_varnish/files/default.vcl b/modules/undine_varnish/files/default.vcl
new file mode 100644
index 0000000..8545903
--- /dev/null
+++ b/modules/undine_varnish/files/default.vcl
@@ -0,0 +1,158 @@
+# This is a basic VCL configuration file for varnish.  See the vcl(7)
+# man page for details on VCL syntax and semantics.
+
+# Default backend definition.  Set this to point to your content
+# server.
+#
+backend default {
+  .host = "127.0.0.1";
+  .port = "1000";
+}
+
+# Respond to incoming requests.
+sub vcl_recv {
+  # Use anonymous, cached pages if all backends are down.
+  if (!req.backend.healthy) {
+    unset req.http.Cookie;
+  }
+
+  # Allow the backend to serve up stale content if it is responding slowly.
+  set req.grace = 6h;
+
+  # Pipe these paths directly to Apache for streaming.
+  #if (req.url ~ "^/admin/content/backup_migrate/export") {
+  #  return (pipe);
+  #}
+
+  if (req.restarts == 0) {
+    if (req.http.x-forwarded-for) {
+      set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
+    }
+    else {
+      set req.http.X-Forwarded-For = client.ip;
+    }
+  }
+
+  # Do not cache these paths.
+  if (req.url ~ "^/status\.php$" ||
+      req.url ~ "^/update\.php$" ||
+      req.url ~ "^/admin$" ||
+      req.url ~ "^/admin/.*$" ||
+      req.url ~ "^/flag/.*$" ||
+      req.url ~ "^.*/ajax/.*$" ||
+      req.url ~ "^.*/ahah/.*$") {
+       return (pass);
+  }
+
+  # Do not allow outside access to cron.php or install.php.
+  #if (req.url ~ "^/(cron|install)\.php$" && !client.ip ~ internal) {
+    # Have Varnish throw the error directly.
+  #  error 404 "Page not found.";
+    # Use a custom error page that you've defined in Drupal at the path "404".
+    # set req.url = "/404";
+  #}
+
+  # Always cache the following file types for all users. This list of extensions
+  # appears twice, once here and again in vcl_fetch so make sure you edit both
+  # and keep them equal.
+  if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
+    unset req.http.Cookie;
+  }
+
+  # Remove all cookies that Drupal doesn't need to know about. We explicitly
+  # list the ones that Drupal does need, the SESS and NO_CACHE. If, after
+  # running this code we find that either of these two cookies remains, we
+  # will pass as the page cannot be cached.
+  if (req.http.Cookie) {
+    # 1. Append a semi-colon to the front of the cookie string.
+    # 2. Remove all spaces that appear after semi-colons.
+    # 3. Match the cookies we want to keep, adding the space we removed
+    #    previously back. (\1) is first matching group in the regsuball.
+    # 4. Remove all other cookies, identifying them by the fact that they have
+    #    no space after the preceding semi-colon.
+    # 5. Remove all spaces and semi-colons from the beginning and end of the
+    #    cookie string.
+    set req.http.Cookie = ";" + req.http.Cookie;
+    set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
+    set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
+    set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
+
+    if (req.http.Cookie == "") {
+      # If there are no remaining cookies, remove the cookie header. If there
+      # aren't any cookie headers, Varnish's default behavior will be to cache
+      # the page.
+      unset req.http.Cookie;
+    }
+    else {
+      # If there is any cookies left (a session or NO_CACHE cookie), do not
+      # cache the page. Pass it on to Apache directly.
+      return (pass);
+    }
+  }
+}
+
+# Set a header to track a cache HIT/MISS.
+sub vcl_deliver {
+  if (obj.hits > 0) {
+    set resp.http.X-Varnish-Cache = "HIT";
+  }
+  else {
+    set resp.http.X-Varnish-Cache = "MISS";
+  }
+}
+
+# Code determining what to do when serving items from the Apache servers.
+# beresp == Back-end response from the web server.
+sub vcl_fetch {
+  # We need this to cache 404s, 301s, 500s. Otherwise, depending on backend but
+  # definitely in Drupal's case these responses are not cacheable by default.
+  if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) {
+    set beresp.ttl = 10m;
+  }
+
+  # Don't allow static files to set cookies.
+  # (?i) denotes case insensitive in PCRE (perl compatible regular expressions).
+  # This list of extensions appears twice, once here and again in vcl_recv so
+  # make sure you edit both and keep them equal.
+  if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
+    unset beresp.http.set-cookie;
+  }
+
+  # Allow items to be stale if needed.
+  set beresp.grace = 6h;
+}
+
+# In the event of an error, show friendlier messages.
+sub vcl_error {
+  # Redirect to some other URL in the case of a homepage failure.
+  #if (req.url ~ "^/?$") {
+  #  set obj.status = 302;
+  #  set obj.http.Location = "http://backup.example.com/";
+  #}
+
+  # Otherwise redirect to the homepage, which will likely be in the cache.
+  set obj.http.Content-Type = "text/html; charset=utf-8";
+  synthetic {"
+<html>
+<head>
+  <title>Page Unavailable</title>
+  <style>
+    body { background: #303030; text-align: center; color: white; }
+    #page { border: 1px solid #CCC; width: 500px; margin: 100px auto 0; padding: 30px; background: #323232; }
+    a, a:link, a:visited { color: #CCC; }
+    .error { color: #222; }
+  </style>
+</head>
+<body onload="setTimeout(function() { window.location = '/' }, 5000)">
+  <div id="page">
+    <h1 class="title">Page Unavailable</h1>
+    <p>The page you requested is temporarily unavailable.</p>
+    <p>We're redirecting you to the <a href="/">homepage</a> in 5 seconds.</p>
+    <div class="error">(Error "} + obj.status + " " + obj.response + {")</div>
+  </div>
+</body>
+</html>
+"};
+  return (deliver);
+}
diff --git a/modules/undine_varnish/files/varnish b/modules/undine_varnish/files/varnish
new file mode 100644
index 0000000..131c75f
--- /dev/null
+++ b/modules/undine_varnish/files/varnish
@@ -0,0 +1,106 @@
+# Configuration file for varnish
+#
+# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
+# to be set from this shell script fragment.
+#
+
+# Should we start varnishd at boot?  Set to "no" to disable.
+START=yes
+
+# Maximum number of open files (for ulimit -n)
+NFILES=131072
+
+# Maximum locked memory size (for ulimit -l)
+# Used for locking the shared memory log in memory.  If you increase log size,
+# you need to increase this number as well
+MEMLOCK=82000
+
+# Default varnish instance name is the local nodename.  Can be overridden with
+# the -n switch, to have more instances on a single server.
+# INSTANCE=$(uname -n)
+
+# This file contains 4 alternatives, please use only one.
+
+## Alternative 1, Minimal configuration, no VCL
+#
+# Listen on port 6081, administration on localhost:6082, and forward to
+# content server on localhost:8080.  Use a 1GB fixed-size cache file.
+#
+# DAEMON_OPTS="-a :6081 \
+#              -T localhost:6082 \
+# 	     -b localhost:8080 \
+# 	     -u varnish -g varnish \
+#            -S /etc/varnish/secret \
+# 	     -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
+
+
+## Alternative 2, Configuration with VCL
+#
+# Listen on port 6081, administration on localhost:6082, and forward to
+# one content server selected by the vcl file, based on the request.  Use a 1GB
+# fixed-size cache file.
+#
+DAEMON_OPTS="-a :80 \
+             -T localhost:6082 \
+             -f /etc/varnish/default.vcl \
+             -S /etc/varnish/secret \
+             -s malloc,256m"
+
+
+## Alternative 3, Advanced configuration
+#
+# See varnishd(1) for more information.
+#
+# # Main configuration file. You probably want to change it :)
+# VARNISH_VCL_CONF=/etc/varnish/default.vcl
+#
+# # Default address and port to bind to
+# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
+# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
+# VARNISH_LISTEN_ADDRESS=
+# VARNISH_LISTEN_PORT=6081
+#
+# # Telnet admin interface listen address and port
+# VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
+# VARNISH_ADMIN_LISTEN_PORT=6082
+#
+# # The minimum number of worker threads to start
+# VARNISH_MIN_THREADS=1
+#
+# # The Maximum number of worker threads to start
+# VARNISH_MAX_THREADS=1000
+#
+# # Idle timeout for worker threads
+# VARNISH_THREAD_TIMEOUT=120
+#
+# # Cache file location
+# VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin
+#
+# # Cache file size: in bytes, optionally using k / M / G / T suffix,
+# # or in percentage of available disk space using the % suffix.
+# VARNISH_STORAGE_SIZE=1G
+#
+# # File containing administration secret
+# VARNISH_SECRET_FILE=/etc/varnish/secret
+# 
+# # Backend storage specification
+# VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
+#
+# # Default TTL used when the backend does not specify one
+# VARNISH_TTL=120
+#
+# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
+# # sure you update this section, too.
+# DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
+#              -f ${VARNISH_VCL_CONF} \
+#              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
+#              -t ${VARNISH_TTL} \
+#              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
+# 	       -S ${VARNISH_SECRET_FILE} \
+#              -s ${VARNISH_STORAGE}"
+#
+
+
+## Alternative 4, Do It Yourself
+#
+# DAEMON_OPTS=""
diff --git a/modules/undine_varnish/manifests/init.pp b/modules/undine_varnish/manifests/init.pp
new file mode 100644
index 0000000..52fa4b7
--- /dev/null
+++ b/modules/undine_varnish/manifests/init.pp
@@ -0,0 +1,59 @@
+# == Class: undine_varnish
+#
+# The undine_varnish class is responsible for the installation of varnish in Undine.
+#
+# It should not be necessary to declare this class directly, as it will be
+# declared automatically by the undine class, which all Undine sites should use.
+#
+class undine_varnish ( $version = '3.0' ) {
+
+  # Installs the GPG key
+  exec { 'import-key':
+    path    => '/bin:/usr/bin',
+    command => 'curl http://repo.varnish-cache.org/ubuntu/GPG-key.txt | apt-key add -',
+    unless  => 'apt-key list | grep servergrove-ubuntu-precise',
+    require => Package['curl'],
+  }
+
+  # Creates the source file for the ServerGrove repository
+  file { 'varnish.repo':
+    path    => '/etc/apt/sources.list.d/varnish.list',
+    ensure  => present,
+    content => "deb http://repo.varnish-cache.org/ubuntu/ precise varnish-${version}",
+    require => Exec['import-key'],
+  }
+
+  exec { "varnish-update-sources-file":
+    command => '/usr/bin/apt-get update',
+    require => File['varnish.repo'],
+  }
+
+  package { 'varnish':
+    ensure => installed,
+    require => Exec['varnish-update-sources-file'],
+  }
+
+  file { '/etc/varnish/default.vcl':
+    owner   => 'root',
+    group   => 'root',
+    mode    => '0444',
+    source  => 'puppet:///modules/undine_varnish/default.vcl',
+    notify  => Service['varnish'],
+    require => Package['varnish'],
+  }
+
+  file { '/etc/default/varnish':
+    owner   => 'root',
+    group   => 'root',
+    mode    => '0444',
+    source  => 'puppet:///modules/undine_varnish/varnish',
+    notify  => Service['varnish'],
+    require => Package['varnish'],
+  }
+
+  service { 'varnish':
+    enable   => true,
+    ensure   => running,
+    require  => Package['varnish'],
+  }
+}
diff --git a/modules/undine_xhprof/files/skettler-php-xhprof-precise.list b/modules/undine_xhprof/files/skettler-php-xhprof-precise.list
new file mode 100644
index 0000000..7bd3b83
--- /dev/null
+++ b/modules/undine_xhprof/files/skettler-php-xhprof-precise.list
@@ -0,0 +1,2 @@
+deb http://ppa.launchpad.net/skettler/php/ubuntu precise main
+deb-src http://ppa.launchpad.net/skettler/php/ubuntu precise main
diff --git a/modules/undine_xhprof/manifests/init.pp b/modules/undine_xhprof/manifests/init.pp
index 59150f2..e515c6d 100644
--- a/modules/undine_xhprof/manifests/init.pp
+++ b/modules/undine_xhprof/manifests/init.pp
@@ -9,7 +9,13 @@
 # declared automatically by the undine class, which all Undine sites should use.
 #
 class undine_xhprof {
-  require undine_php
+
+  undine_apt::ppa { 'skettler/php':
+    ppa_user => 'skettler',
+    ppa_name => 'php',
+    source_list_d_filename => 'skettler-php-xhprof-precise.list',
+    source_list_d_source => 'puppet:///modules/undine_php/skettler-php-xhprof-precise.list',
+  }
 
   package { "php53-xhprof":
     ensure => installed,
diff --git a/www/README b/www/README
deleted file mode 100755
index 716babb..0000000
--- a/www/README
+++ /dev/null
@@ -1,7 +0,0 @@
-DO NOT DELETE THIS DIRECTORY.
-
-This directory is used by Undine to support a shared directory between
-the Undine VM and the host OS. This makes it possible to modify files
-in your IDE of choice on the host OS while serving them via Undine.
-
-For more information, please review the documentation.
