Pulling Strings With Puppet - James Turnbull [38]
If we want to retrieve a file in the configuration module, we would use the file resource type as you can see in Listing 4-13.
In Listing 4-13, we've retrieved the nsswitch.conf file from our Puppet master server, here puppetmaster. The source attribute of the file type allows us to specify the location of the file to be retrieved. It takes the format of
In our listing, the server name is puppetmaster and the module is our previously defined configuration. We then specify the source file to be retrieved. If you omit the server value, for example, puppet: ///module/file, Puppet will automatically try to fill in the value of the server name based on the Puppet master server that you are connecting to.
We can also download the contents of whole directories recursively using the recurse attribute like so:
Instead of specifying a file in the file resource type, we specify a directory. The source statement also specifies a directory located on our file server. The recurse attribute tells Puppet that all files contained in the source directory should be retrieved and downloaded to the target node.
Tip - You can also copy from more than one source by specifying multiple entries in the source attribute. You can see details of how to do this in the Type Reference at http://reductivelabs.com/trac/puppet/wiki/TypeReference#file.
Modularizing Our Configuration
Now that we've configured the basics of our nodes and introduced user management and file serving, we need to add some services, like mail, databases, and web services, to our nodes. We're going to configure MySQL on our db.testing.com node, the Postfix mail server on our mail.testing.com node, and finally Apache on our www.testing.com node.
To add these services, we're going to use one of Puppet's more powerful features: modules. Modules are collections of configuration-manifests, templates, and files-that can be reused and distributed. For example, instead of creating individual classes for installing and managing MySQL, we're going to create a MySQL module.
So why use modules? Well, if the application, daemon, or function you are configuring contains multiple classes, files, and/or templates, the easiest way to package these resources is to modularize them. Modules make management of configuration collections easier and more structured.
Modules are structured very simply. They are stored under a directory specified in the modulepath configuration variable in the puppet. conf configuration file or on the command line using --modulepath. By default, these are the $confdir/modules (/etc/puppet/modules in most installations) and /usr/share/puppet/modules directories. We can also specify multiple module paths as colon-separated lists of directories like so:
Modules are then included into your configuration using the import function as you can see in Listing 4-14.
Tip - From version 0.23.1, Puppet tries to automatically load classes and definitions contained in your module path. This means if you want to use a specific class or definition from your module in your configuration, you can simply include the class or start using the definition without needing to explicitly import the whole module.
So how does Puppet know what resources to load? Each module is defined using a directory structure and an initialization file called the init. pp file. Each module should have a minimum of the following directory structure:
Tip • It is often useful to put a README file in the root directory of the module that describes your module and its structure, files, and any dependencies.
The it. pp file, which is automatically processed when you import a module, should be located in the module_name/manifests directory. For example, if we had a module called mysql located in the default modules directory, Puppet would expect to find the init. pp file in the following location:
The init. pp file has a dual function. It can contain the core classes used in the module or provide a location from