Automating lighttpd installations with Puppet – Part 2

In Part 1 of this series, we configured our puppetmaster to make sure that our nodes would get an installation of lighttpd up and running quickly. Now to get a smarter environment where you don’t have to add all the stuff we added into every node-block for every web server host, we’ll create our very own module. Module are smart ways of getting stuff up and running really fast, and right now as of today (August 14th 2012) the number of publicly available modules over at forge.puppetlabs.com are 459. With this huge amount of already available modules for different services such as ntp, apache, mysql and spamassassin, you will most probably not have to write your own module for what you would like to do. But this Part 2 will show you how to get started by creating a small lighttpd-module, and perhaps yours will be the next one up on the Forge?

If you’ve followed the Razor + Puppet posts you will already have played around with modules a bit, maybe even without thinking about it. So let’s go through what modules do and why you should care.

Modules create a portable configuration where you can use their default settings to get a specific thing done, such as installing a package and getting a service up and running. Modules are also flexible, in a way that you can manipulate the settings of said installation and service to do your bidding.

Let’s create our own module for a lighttpd installation, so that we can easily deploy more of those lighttpd servers wihout having to configure every one of them with a ton of configuration code (remember the One configuration to Many installations part?).

First, let’s create a directory structure. It should look like this:

/etc/puppet/modules/lighttpd
                       |
                       - files
                       - lib
                       - manifests

In the “files” directory, create a new file called “index.html”. We’ll use this as our starting page for all new lighttpd installations. Put something in the file, anything you’d like. I put the following into it:

<h1>Hello World!</h1>

Ok, so we have our directory tree, and we have a file that we want to be copied over to the web server host as soon as lighttpd gets installed, or is already installed. Let’s take the code that we had in our nodes.pp file and copy that into a module class so we can easily resuse it. Create new file at /etc/puppet/modules/lighttpd/manifests/init.pp:

class lighttpd {
    package {
        'lighttpd':
        ensure => installed
    }
    service {
        'lighttpd':
        ensure => running,
        enable => true,
        require => Package['lighttpd']
    }
}

It’s essentially the exact same code we used before, with the addition that we’re now calling it a “class”. Classes in modules defines what should happen, in this instance we’re defining the installation of the lighttpd package and then we’re defining that the service should be running.

Let’s add our index.html file into the mix:

class lighttpd {
    package {
        'lighttpd':
        ensure => installed
    }
    service {
        'lighttpd':
        ensure => running,
        enable => true,
        require => Package['lighttpd']
    }
    file { "/var/www/index.html":
        ensure => present,
        owner => 'root',
        group => 'root',
        mode => 0644,
        source => "puppet:///modules/lighttpd/index.html",
        require => Package['lighttpd']
    }
}

We have here defined where the file should be placed, who should be set as owner, what the permissions should be and which file we should use as source. (Update August 17th) Also, we require the package “lighttpd” to be installed first, otherwise it’s not useful to make sure the file is there. For clarification, the puppet:/// is a URI, so the files-directory can be omitted when we call for regular files here, and that’s why we don’t write “puppet:///modules/lighttpd/files/index.html”.

Perfect, but we still have a lot of crap about lighttpd installation and services in the nodes.pp file. Isn’t this just all a waste if we need to define stuff all over the place? Yes, it would be. Therefore, let’s clean up our nodes.pp file:

node "35553b90abfc012f4380000c293a4170" inherits default {
 include lighttpd
 }

Much cleaner! That’s all we need now to fully install lighttpd, make sure the service is started and place an index.html file in the base web directory.

Let’s run the puppet agent on our node in noop mode:

root@node9:~# puppet agent --noop --test
<snip>
notice: /Stage[main]/Lighttpd/File[/var/www/index.html]/ensure: current_value absent, should be file (noop)
notice: Class[Lighttpd]: Would have triggered 'refresh' from 1 events
<snip>

Here we can see that the puppet agent considers the index.html to be missing, and will copy the new file during the next proper run. Let’s try it:

root@node9:~# puppet agent --test --verbose
<snip>
notice: /Stage[main]/Lighttpd/File[/var/www/index.html]/ensure: defined content as '{md5}63dc6718a6cc98446a099f6a22d254cf'
<snip>

Perfect! Let’s browse to our web servers IP and see what we find:

Amazing! You’ve now completed numerous tasks in your effort to deploy lighttpd with Puppet:

  1. Created your own module (will I see it up on PuppetForge any time soon?)
  2. Verfied that the module worked
  3. Cleaned up your nodes.pp file

Let’s do one more thing before we close this post. Let’s imagine you would like to do a change on your web site to include something other than “Hello World!”. Perhaps another text, like “You Are Awesome!”. To do this, follow these simple steps:

Edit your index.html file, and run the puppet agent again. No config necessary. Browse to your web server, and what will you find?

Yes, Yes You Are 🙂

Advertisements

About Jonas Rosland

Open Source Community Manager at {code} by Dell EMC
This entry was posted in Automation, Installation, IT Transformation, Puppet, VMware and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s