How to create class and module in puppet

In my previous article (“How to automate your IT infrastructure with puppet“) I showed you how to install and configure puppet, and how to write simple manifest.Today I’ll show you how to write those simple manifest using puppet classes and modules using the same server environment.

What is class and module

So what are class and modules? Those who have experience or have some knowledge about Object-oriented programming (OOP), let me clear one thing to you that the concept is not same in puppet. Classes are named blocks of Puppet code that are stored in modules for later use and are not applied until they are invoked by name. Yes creating puppet class has no impact in the catalog until unless you call them in the manifest. We will see it soon.

Defining class

Before we can use the class we need to define it first. We can do it by using the class keyword, a name (must begin with lower case, underscore and number can be used after that), curly braces opening and closing and in between those braces a chunk of puppet codes.

class
class_name1 {
  codes....
  codes.....
}

Declaring class

Defining the class has no impact in the manifest means it never executes that codes inside the curly braces until unless we declare them. Follow the below procedure to declare a class.

include class_name1

This time the resources of the class (codes…) will be executed. When I learn about puppet class i was confused about the term called defining and declaring. To avoid confusion always remember that defining a class means you only create that class but to make it working you have to declare it and as you saw it simple just use include keyword in front of the class name. Class can be declared with or without parameter. You can find more about puppet class here.

Modules

We can deploy all our puppet code in one single file. But that will be difficult for reading and also it’s difficult to understand. To keep puppet code simple and clean we can use modules. Modules are collection of manifest, data like fact, files, templates etc. Another feature of module is that it has a specific directory structure. For best practice it is advisable to use all your puppets manifest in modules. You can find more about puppet modules here.

Module Structure

In simple word module is a directory with some other directory in it. By default puppet keeps modules in “/etc/puppetlabs/code/environments/production/modules” directory.

└── modules
    └── system_user
        ├── examples
        ├── files
        ├── manifests
        │   └── init.pp
        └── templates

As you can see above the structure of a module. Here I create a module (or Directory) name system_user and within that system_user directory i created another four directory name examples, files, manifests, templates. The name of the module (system_user) and the directory (system_user) name should be same. Each of this directory has a specific purpose and you should follow the exact name I use here. For simplicity, I will only describe the manifests directory which actually contains the main puppet code. Every module has a manifests directory and this directory should contain a init.pp file where the main definition of the module is written. A single class definition should present in that file and the class name should be the same as the module’s name.

So far we have learned what is a class in puppet, how to define and declare a class, what is a module, what is the structure of a module, how to create module, where to put the class file inside that module. Lets see this in practical now.

Create module

As we already know that puppet keeps its module in /etc/puppetlabs/code/environments/production/modules” directory. Let’s go to that directory and create our first module or in other word lets create a directory inside the modules directory.

imtiaz@master:cd /etc/puppetlabs/code/environments/production/modules$
sudo mkdir system_user

A directory/module called system_user is created in the modules directory. Let’s build the structure of our module.

cd system_user/
sudo mkdir {examples,files,manifests,templates}

As you can see that four directories has been created inside system_user directory which create the structure of our module.

Let’s create the init.pp file inside manifests directory.

cd manifests/
sudo vim init.pp

Create/Define class

Let’s create or define our first puppet class called system_user. Insert the bellow code in init.pp file.

class system_user{
    user { 'sysuser1':
    ensure => present,
    comment => 'System User',
    home => '/home/sysuser1',
    managehome => true,
    password => '$1$zUd5n2PQ$LQfmzV5TBaO0S9E8PtDyx0'
   }
 }

Take a look at the class name, as I say earlier, it should start with lower case and the name of the class and the module is similar. I have already shown how to create the password in my previous tutorial name “How to automate your IT infrastructure with puppet“. You can follow that tutorial for creating the password. Run the below command to check your code:

puppet parser validate init.pp

If nothing is returned, then the code is ok. For error the error message will be displayed on the screen.

Call/Declare class

After defining the class, it’s time to declare it. Let’s go to the “/etc/puppetlabs/code/environments/production/manifests” folder. Again in my previous article we created a file called site.pp in that folder. Let’s change that file.

sudo vim site.pp

Delete everything from that file and paste the below text in that file:

node 'agent1.traininglab.local' {
        include system_user
}

node 'default' {
}

As you can see to activate the class we need to declare it using the keyword include. The node keyword will help to run the puppet code in that specific node. Let’s go to the “agent1.traininglab.local” node and run the below command.

[imtiaz@agent1 ~]$ sudo puppet agent --test
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for agent1.traininglab.local
Info: Applying configuration version '1477915818'Notice: /Stage[main]/System_user/User[sysuser1]/ensure: created
Notice: Finished catalog run in0.09 seconds
[imtiaz@agent1 ~]$

You will see an output like above. Note the line “Notice: /Stage[main]/System_user/User[sysuser1]/ensure: created” which ensure that the user sysuser1 has been created in the specific node. Now if you want to create that user in your other nodes just modify the site.pp script like block below:

node 'agent1.traininglab.local' {
        include system_user
}

node 'agent3.traininglab.local' {
        include system_user
}

node 'default' {
}

If you run “puppet agent –test” in that node, then it will create the same user in that node. As you can see we can use that class as many times as we like in different nodes. That’s the benefit of using class and module. Write one time use many times. That’s all for today. Take care and good by.

If you enjoyed the post, please share it with your network and let me know your thoughts in the comments. 

About the Author: Imtiaz is working in a financial organization in Bangladesh and having experience in system, network and security administration. Feel free to contact with him on LinkedIn or Twitter

Leave a Reply

Your email address will not be published. Required fields are marked *