name-based virtual web server

This module is used to create a name-based apache2 virtual web-server on the Debian distribution.

Usage is:

node virt-webservers {

include apache2

apache2::vhost { "ws.tsand.org":

serveradmin => "email_address@gmail.com",

serverfqdn => "ws.tsand.org",

}

apache2::vhost { "wsa.tsand.org":

serveradmin => "email_address@gmail.com",

serverfqdn => "wsa.tsand.org",

suexec => true,

suuid => 2021,

sugid => 2021,

}

apache2::vhost { "wsb.tsand.org":

enable => false,

serveradmin => "email_address@gmail.com",

serverfqdn => "wsb.tsand.org",

}

}

In the above example, I can merely use the inherit statement when declaring a node, for example:

node n1.tsand.org inherits virt-webservers {

....

}

Thus, 3 virtual web-servers (ws.tsand.org, wsa.tsand.org and wsb.tsand.org) will be created on node n1.tsand.org.

My goal was to make the declaration of a new virtual web server as simple as possible.

Options are:

serveradmin -> email address of web-site administrator

serverfqdn -> fully qualified domain name. As these are name-based virtual web-servers, you must ensure that DNS has a coresponding entry.

enable --> default is true. Set to false to disable the site.

suexec --> default is false. If set to true, then suuid (uid) and sugid (gid) must be declared.

suuid --> user id for suexec

sugid --> group id for suexec

The module has the following presumptions:

    1. The directory to hold the web-site content is /var/www/sites.

    2. Each site is declared using it's FQDN. For example, web-site ws.tsand.org would use directory /var/www/sites/ws.tsand.org

    3. Document root is assumed to be htdocs, under the site directory. For example /var/www/sites/ws.tsand.org/htdocs.

    4. The cgi-bin directory is assumed to be cgi-bin, under the site directory. For example /var/www/sites/ws.tsand.org/cgi-bin.

    5. The log files are placed in /var/log/apache2 and are named as $fqdn_error.log & $fqdn_access.log.

    6. The web-server definition is placed in /etc/apache2/sites-available, and is named as the $fqdn.

    7. If a site is enable, a symbolic link is created between /etc/apache2/sites-enabled & /etc/apache2/sites-available.

    8. The web-server definition is created using a template, therefore any manual modification to the web-site definition will be lost at the next puppet client execution cycle. To allow manual customization of the web-server definition, an additional file $fqdn_custom is included at the end of the web-server definition file created by puppet. The administrator my modify the $fqdn_custom file as needed. The custom file is /etc/apache2/sites-available/$fqdn_custom.

    9. The module will ensure the following packages are loaded:

      1. apache2

      2. php5

      3. apache2-suexec

    10. The module will ensure that apache2 is always running.

    11. The module will ensure that /var/www/sites directory exists. I would recommend making this a mount point for a separate filesystem.

    12. A site can be disable by adding the "enable => false" option. The default is "enable => true".

    13. The apache2-suexec module is included. To use it you must declare "suexec => true", and "suuid => some_uid", and "sugid => some_gid" in your vhost declaration. There is NO validation on the selected uid & gid.

There are only 2 files in this module:

    1. /etc/puppet/modules/apache2/templates/vhost.erb

    2. /etc/puppet/modules/apache2/manifests/init.pp

Here is the /etc/puppet/modules/apache2/templates/vhost.erb file:

# /etc/puppet/modules/apache2/templates/vhost.erb

# vi:set nu ai ap aw smd showmatch tabstop=4 shiftwidth=4:

<VirtualHost *>

ServerAdmin <%= serveradmin %>

ServerName <%= serverfqdn %>

<% if suexec != false then %>

SuexecUserGroup <%= suuid %> <%= sugid %>

<% end %>

DocumentRoot /var/www/sites/<%= serverfqdn %>/htdocs/

<Directory />

Options FollowSymLinks

AllowOverride None

</Directory>

<Directory /var/www/sites/<%= serverfqdn %>/htdocs/>

Options Indexes FollowSymLinks MultiViews

AllowOverride None

Order allow,deny

allow from all

</Directory>

ScriptAlias /cgi-bin/ /var/www/sites/<%= serverfqdn %>/cgi-bin/

<Directory "/var/www/sites/<%= serverfqdn %>/cgi-bin/">

AllowOverride None

Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

Order allow,deny

Allow from all

</Directory>

ErrorLog /var/log/apache2/<%= serverfqdn %>_error.log

LogLevel warn

CustomLog /var/log/apache2/<%= serverfqdn %>_access.log combined

include /etc/apache2/sites-available/<%= serverfqdn %>_custom

</VirtualHost>

Here is the /etc/puppet/modules/apache2/manifests/init.pp file:

# /etc/puppet/modules/apache2/manifests/init.pp

# vi:set nu ai ap aw smd showmatch tabstop=4 shiftwidth=4:

# class to create & manage debian apache2 name-based

# virtual web-servers

# NOTE: This module was designed for Debian apache2 structure.

# It must be modified to support other distributions.

class apache2 {

Exec { path => ['/bin','/usr/bin','/sbin','/usr/sbin'] }

# ensure that the apache2 package is installed

package {

"apache2":

ensure => present;

"php5":

ensure => present;

"apache2-suexec":

ensure => present;

}

# ensure it is running

service { "apache2":

ensure => running,

}

# I don't think it's best to allow puppet to ensure the web service is always running.

# I intend to put web-services control under heartbeat and configured as a clone.

# This would mean that heartbeat controls the start/stop; and besides, how else could

# I stop the service otherwise to do things like maintenance?

# ensure suexec is installed

exec { "a2enmod suexec":

creates => "/etc/apache2/mods-enabled/suexec.load",

}

# ensure the sites directory exists

file { "/var/www/sites":

ensure => directory,

owner => root,

group => root,

mode => 0644,

}

# create a name-based virtual host

define vhost($serveradmin,$serverfqdn,$enable=true,$suexec=false,$suuid="www-data",$sugid="www-data") {

$site = "/var/www/sites/${serverfqdn}"

$docroot = "${site}/htdocs"

$cgidir = "${site}/cgi-bin"

$siteconfig = "/etc/apache2/sites-available/${serverfqdn}"

$sitecustom = "${siteconfig}_custom"

$siteenabled = "/etc/apache2/sites-enabled/${serverfqdn}"

# create the site docroot & cgi-bin

file {

# create the /var/www/sites/fqdn directory

$site:

ensure => directory,

owner => root,

group => root,

mode => 0644,

require => [

Package['apache2','apache2-suexec','php5'],

File["/var/www/sites"],

];

# create the /var/www/sites/fqdn/htdocs directory

$docroot:

ensure => directory,

owner => root,

group => root,

mode => 0644,

require => [

Package['apache2','apache2-suexec','php5'],

File[$site],

];

# create the /var/www/sites/fqdn/cgi-bin directory

$cgidir:

ensure => directory,

owner => root,

group => root,

mode => 0644,

require => [

Package['apache2','apache2-suexec','php5'],

File[$docroot],

];

# create the /etc/apache2/sites-available/fqdn file

$siteconfig:

ensure => present,

owner => root,

group => root,

mode => 0644,

content => template("apache2/vhost.erb"),

require => [

Package['apache2','apache2-suexec','php5'],

File[$cgidir,$docroot],

];

# create the /etc/apache2/sites-available/fqdn_custom file

$sitecustom:

ensure => present,

owner => root,

group => root,

mode => 0644,

require => [

Package['apache2','apache2-suexec','php5'],

File[$siteconfig],

];

}

# enable or disable the site & restart apache2

if $enable == true {

exec { "enable site $serverfqdn":

# command to run

command => "a2ensite $serverfqdn",

# condition for command to run

unless => "test -L ${siteenabled}",

# ensure these requirements are in place before run

require => [

Package['apache2','apache2-suexec','php5'],

File["${siteconfig}"],

File["${sitecustom}"],

],

# and restart apache2

notify => Service[apache2],

}

} else {

exec { "disable site $serverfqdn":

# command to run

command => "a2dissite $serverfqdn",

# condition for command to run

onlyif => "test -L ${siteenabled}",

# ensure these requirements are in place before run

require => [

Package['apache2','apache2-suexec','php5'],

File["${siteconfig}"],

File["${sitecustom}"],

],

# and restart apache2

notify => Service[apache2],

}

}

}

}