DevOps Series – Automation with Puppet – Part5
Understanding Puppet Modules
Modules are directories that contain configuration information. Modules have predefined structures. An example module is openssh, which not only installs OpenSSH on a client, but also configures it. Modules can be shared easily with others.
Numerous modules are available on Puppet Forge (https://forge.puppetlabs.com/).
Before creating your own module, check to see if an existing module works for you. An important issue with modules is being able to trust them, because they can be written by anyone. There are certain modules that are in the Puppet Labs name space; perhaps those may be more trustworthy than other modules.
Modules allow autoloading of classes, file serving for templates and files, and autodelivery of custom Puppet extensions. The location of modules is specified in the Puppet configuration file:
[master] modulepath = /etc/puppet/modules
Puppet modules use classes. A Puppet class is a collection of code that references some resources. Classes have to be defined and then declared. Defining a class is done using the term class. To declare the class, you use the term include. Without declaring a class, you are not using it. An example of defining a class and using it follows:
#define a class called ssh
class ssh {
package { 'openssh-clients':
ensure => present,
}
}
#declare the ssh class, which causes it to be invoked
node 'www.example.com' {
include ssh
}
The default storage location of a module is /etc/puppet/modules. Modules are directory trees. If we were to create a module for myapp ( as shown below), then in /etc/puppet/modules, you would expect to find a directory called myapp.
Under that directory would be five other directories: manifests, templates, files, tests, and facts.d. In each of these directories are files relating to the specific module component. The init.pp file is where it all begins, because it contains the module class.
Templates are in the templates directory for any configuration you may have. The files directory stores any files the module might install, and they are accessible with the path puppet:///modules/myapp/index.html.tests also containsinit.pp and is used by Puppet to test the module if you so wish. If you have any custom facts that this app shares, they would be stored in facts.d directory.
myapp Module Directory Structure
- myapp - manifests - init.pp - templates - app.erb - files - index.html - tests - init.pp - facts.d - myapp.rb
Understanding Hiera
Hiera is a key-value data store that is external to Puppet but can be called from Puppet. The advantage of using Hiera is that you can separate code from data. This feature makes it a lot easier to read code and reuse code. To understand Hiera more completely, let’s take a look at code with Hiera and without Hiera.
class ntp { if ( $::environment == 'development' ) { $ntpserver = '10.1.1.100' } else { $ntpserver = '10.1.2.100' } class { 'ntp::client': server => $ntpserver, }
We have two different NTP servers: 10.1.1.100 and 10.1.2.100. Based on the environment, we want to assign the appropriate NTP server. If the number of sites or environments increases, the if‥else statement has to accommodate each of them by adding more ‥else statements.
Using Hiera, we can simplify the code to look like this:
class { 'ntp::client': server => hiera('ntpserver','us.pool.ntp.org') }
In Hiera, you can then place the different NTP servers, and Puppet will pick based on the appropriate value.