Friday Fun With Vortex and Puppet

It is Friday so let's explore something fun. In this post we would like to show you how you can use Vortex (internal project of ours - now public and open source) to quickly start your next web application project. It takes no time to get going.

What is Vortex

Vortex is virtual machine management tool, which allows you to, well, manage virtual machines but on multiple virtualization platforms (a.k.a. providers). You can use Vortex with VirtualBox or with Amazon EC2. The key benefit of a project like Vortex is that you do all activities from a single place vs. working with VirtualBox and Amazon separately, plus you get the added benefit of automating some tasks such as installing packages, preparing the environment, etc.

Vortex is excellent for development purposes. You start by developing and testing your project locally in VirtualBox. Once you are satisfied with all changes you can use the same toolkit to deploy the project in a production environment. The production environment should be almost an exact replica of your development environment, which improves stability and reduces the chance for unexpected behaviour.

Vortex and Puppet

Vortex comes with a default provisioner called Roost - another project of ours. Roost is responsible for running various types of commands once the virtual machine is started in order to ensure some kind of consistency. You can use roost to install packages, start and stop service, load files and of course run all kinds of commands.

Although Roost is very flexible and built to support all kinds of things it is not as mature as Puppet or Chef because it lacks the development community behind it. We are developing some plugins but for internal use only. However, Roost can be integrated with Puppet easily. Let's explore how this is done in a sample web project for mongo and php.

Your Next Web App

First we will use the following folder structure:

./puppet/
	./manifests/
		./default.pp
	./modules/
./app/
	./index.php
./vortex.json

At the top of the folder you need a file called vortex.json. This is where you need to put our Vortex and Roost configurations. For the purpose of this project will use the following config:

{
  "namespace": "you-next-web-app",

  "virtualbox": {
    "vmId": "precise64",
    "vmUrl": "https://s3.amazonaws.com/node-vortex/precise64.ova",
    "username": "vortex",
    "password": "vortex"
  },

  "nodes": {
    "app": {
      "expose": {
        "./puppet": "/puppet",
        "./app": "/app"
      },

      "roost": {
        "apt": {
          "update": true
        },

        "packages": ["puppet"],

        "commands": [
          "sudo puppet apply --verbose --modulepath /puppet/modules/ /puppet/manifests/default.pp"
        ]
      }
    }
  }
}

What this means reading from top to bottom is: Define a project with namespace your-next-web-app. This is done for name collision purposes and to keep your projects tidy. Setup the default configuration for VirtualBox since this is what we will use for this project. Inside the nodes section define a single node which is called app. Expose the local ./puppet and ./app folders to the virtual machine in folders /puppet and /app respectively. For Roost, ensure that apt is updated and puppet is installed. After that run puppet.

This is really all you need to get started.

Now that we have this covered we need to configure puppet. For this project we will use the following config:

class mongodb-setup {
	class { 'mongodb':
		enable_10gen => true,
	}
}

class php-setup {
	package { 'php5':
		ensure => installed,
	}

	package { 'php-pear':
		require => Package['php5'],
		ensure => installed,
	}

	exec { '/usr/bin/pecl install mongo || true':
		require => Package['php-pear'],
	}

	file { '/etc/php5/conf.d/mongo.ini':
		require => Exec['/usr/bin/pecl install mongo || true'],
		content => 'extension=mongo.so',
		notify => Service['apache2'],
	}
}

class apache-setup {
	class { 'apache':
		mpm_module => 'prefork',
	}

	class { 'apache::mod::php':
	}

	apache::vhost { 'your-next-web-app':
		default_vhost => true,
		port => '80',
		docroot => '/app',
		docroot_owner => 'root',
		docroot_group => 'root',
		override => ["All"],
	}
}

include mongodb-setup
include php-setup
include apache-setup

So what this essentially describes is how to setup the entire application environment. As you can see we install mongo. We also setup php with the mongo driver. Finally we configure Apache with our application. Needless to say you will need the following puppet modules installed inside the puppet/modules folder: apache, apt, concat, mongodb and stdlib.

In order to boot this application environment and start playing you need to launch roost. The command for this is simple: vortext up. In order to open the app inside your default browser, do vortext openurl.

This is it. To learn more about Vortex and how to use it with Puppet, just see some of the examples on GitHub. If you have any questions, just let us know.