Chapter 6. Custom Types

Puppet is about configuration management. As you write more and more code in Puppet, patterns will begin to emerge—sections of code that repeat with minor differences. If you were writing your code in a regular scripting language, you'd reach for a function or subroutine definition at this point. Puppet, similar to other languages, supports the blocking of code in multiple ways; when you reach for functions, you can use defined types; when you overload an operator, you can use a parameterized class, and so on. In this chapter, we will show you how to use parameterized classes and introduce the define function to define new user-defined types; following that, we will introduce custom types written in Ruby.

Parameterized classes

Parameterized classes are classes in which you have defined several parameters that can be overridden when you instantiate the class for your node. The use case for parameterized classes is when you have something that won't be repeated within a single node. You cannot define the same parameterized class more than once per node. As a simple example, we'll create a class that installs a database program and starts that database's service. We'll call this class example::db; the definition will live in modules/example/manifests/db.pp, as follows:

class example::db ($db) {
  case $db {
    'mysql': {
      $dbpackage = 'mysql-server'
      $dbservice = 'mysqld'
    }
    'postgresql': {
      $dbpackage = 'postgresql-server'
      $dbservice = 'postgresql'
    }
  }
  package { "$dbpackage": }
  service { "$dbservice": 
    ensure  => true,
    enable => true,
    require => Package["$dbpackage"] 
  }
}

This class takes a single parameter ($db) that specifies the type of the database: in this case either postgresql or mysql. To use this class, we have to instantiate it, as follows:

class { 'example::db': 
  db => 'mysql'
}

Now, when we apply this to a node, we see that mysql-server is installed and mysqld is started and enabled at boot. This works great for something similar to a database, since we don't think we will have more than one type of database server on a single node. If we try to instantiate the example::db class with postgresql on our node, we'll get an error, as shown in the following screenshot:

Parameterized classes

This fails because we cannot reuse a class on the same node. We'll need to use another structure, the defined type that we'll cover shortly. But first, we'll look at one of the language improvements in Puppet 4.

Data types

The preceding example's parameterized class does not take advantage of the new Puppet language features in version 4. Version 4 of the Puppet language supports explicit data types. Data types in previous versions had to be determined by comparing items and often hoping for the best. This led to some bad practices, such as using the string value true to represent the Boolean value True. Using the version 4 syntax, we can change the preceding class to require the $db parameter to be a string, as shown:

class example::db (String $db) {
  case $db {
    'mysql': {
      $dbpackage = 'mysql-server'
      $dbservice = 'mysqld'
    }
    'postgresql': {
      $dbpackage = 'postgresql-server'
      $dbservice = 'postgresql'
    }
  }
  package { "$dbpackage": }
  service { "$dbservice":
    ensure  => true,
    enable => true,
    require => Package["$dbpackage"]
  }
}

The ability to know the type of a parameter has been a long-standing bug with Puppet, particularly when dealing with Boolean values. For more information on the data types supported by Puppet 4, refer to the documentation page at https://docs.puppetlabs.com/puppet/latest/reference/lang_data_type.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset