As we saw in the ntp
example,
classes are great for organizing our configurations, but they can also
enhance the reusability of our code. Classes in Puppet, unlike define
types, are not like their instanceable namesake in other object-oriented
programming languages. They will take parameters and can even inherit
structure from other classes, but only one class of a particular name can
exist on each node.
We can build a base class that installs our Apache2 package and sets up a service to manage it. We can then inherit from the base and add a couple of special-purpose classes for an Apache with SSL and Apache with PHP. This helps to reduce duplication in our code and makes future changes less onerous:
class http-server { package { "apache2": ensure => installed } service { "apache2": ensure => running, enable => true, pattern => "apache2", subscribe => Package["apache2"], } } class https-server inherits http-server { exec { "a2enmod ssl": creates => "/etc/apache2/mods-enabled/ssl.load", notify => Service["apache2"], } } class http-php-server inherits http-server { package { "libapache2-mod-php5": ensure => installed } exec { "a2enmod php5": creates => "/etc/apache2/mods-enabled/php5.load", notify => Service["apache2"], } file { "/etc/php5/apache2/php.ini": source => "puppet:///modules/apps/php5/php.ini", notify => Service["apache2"], } }
We can also pass parameters into classes when we include them in a
node. Say we need to install different package versions on different
systems. We can build a class that accepts a parameter $version
and then passes that on to a package
resource inside.
Here I’ve built a class called ruby
that accepts a parameter named version
that has a default value of ‘1.8’. Then
I’ve declared the ruby
class in my
example node, passing the version ‘1.9.1’. If I omit the version
parameter, the package will be installed with the default value, but I am
otherwise allowed to override the version with whatever I choose:
class ruby ( $version = '1.8') { $package_list = ["ruby$version", "ruby$version-dev", "rubygems$version", "libopenssl-ruby$version",] package { $package_list: ensure =>installed, } } node "test.example.com" { class { 'apps::ruby': version => "1.9.1", } }
In the last example, I built an array of package names and passed them into a package resource. This is an example of a custom variable declaration.