Author: Jacob Mammoliti

I was recently asked if it was possible to have hosts in a Satellite environment look at different NTP servers based on a group they belong to. For example, have hosts in the development stage look at NTP server A and have hosts in the production stage look at NTP server B. With the use of host groups and parameters, a Puppet module will be customized for each host based on the parameters it is given from the host group it belongs to.

This post will show you how to:

  • create a custom Puppet module with Smart Class Parameters
  • create a Product in Satellite for your module(s)
  • edit parameters on a per Host Group basis

The full GitHub repo can be found here.

Generating a New Module Boilerplate

The first step to create a Puppet module is to create a basic module structure. The easiest way is to use Puppet’s built in module generator to do this for us.

We will generate the Puppet module and then edit the main Puppet module file.

~]# puppet module generate [arctiqjacob-ntp]
~]# vim arctiqjacob-ntp/manifests/init.pp


class ntp($servers=[''],
          $iburst=true,) {

  package {'ntp':
    ensure => installed,

  file {'/etc/ntp.conf':
    ensure => file, # Ensure file exists and is a file
    content => template('ntp/ntp.erb'), # Desired contents of file

  service {'ntpd':
    ensure => running,
    enable => true,
    hasstatus => true,
    hasrestart => true,

The above script takes in two parameters, a server list of type array and an iburst of type boolean. The script first checks that the ntp package is installed on the system and then ensures a configuration file is present with the desired contents which comes from the template. The last block of code makes sure the ntpd service is running and is enabled.

The next step is to create the template that the above module is looking at. For the most part, it is just a standard ntp configuration file but the difference comes in with the piece of code below which takes the array of servers, loops through the array and then prints out each server into the ntp configuration file. It also looks at the iburst parameter and if it is set to true, iburst is placed at the end of each line. The full configuration file can be found in the GitHub repository.

~]# cd arctiqjacob-ntp
arctiqjacob-ntp]# mkdir templates
arctiqjacob-ntp]# vim templates/ntp.erb


<% [@servers].flatten.each do |server| -%>
server <%= server %><% if @iburst == true -%> iburst <%end%>
<% end -%>

Packing Up the Module

Once the template is created, the module is compressed so it can be imported into Satellite.

arctiqjacob-ntp]# cd ..
~]# puppet module build arctiqjacob-ntp/

There will now be a ZIP file located at arctiqjacob-ntp/pkg/.

Creating a Custom Product in Satellite

In order to import the module into Satellite, a custom product needs to be created which is where all of the custom Puppet modules will sit.

  1. Log into Satellite and go to Content -> Products
  2. Click + New Product
  3. Provide a Name and Description and click Save
Create Product

Now that the Product is created, we can create the repository for the Puppet module.

  1. Back on the Products page, click the newly created product
  2. In the Repositories subtab, click Create Repository
  3. Provide a Name and choose Puppet as the Type and click Save
Create Repository

Final step is to add the Puppet module to the repoistory.

  1. Click the name of the newly created repository
  2. In the Upload Puppet Module section, click Browse and the select the module that we packaged up earlier
  3. Click Upload
Upload Puppet Module

The Puppet module is now available in Satellite and can be added to a content view.

Head to Content -> Content Views and click + Create New View and create a similar content view as shown below. We want to create a seperate content view for our Puppet module for best practices and then layer it together with core content views using composite content views.

Create a Content View

Once created, click on the Puppet Modules tab and click + Add New Module. You will see the recently created ntp module, click the Select Version button and then click the Select Version button again next to the latest version.

Click on Publish New Version to create the first version of this content view. Upon completion, you should see a page very similar to below. Typically a Satellite environment will have multiple lifecycle environments and this content view would now be promoted into its appropriate view. For simplicity of this tutorial, I have left in Library.

Publish Content View

Head over to Configure -> Classes to edit the Puppet class. Find the ntp row and under Actions, click Override all parameters. This will allow us to edit the parameters at the host group level.

Now click on Configure -> Host groups and create a new host group. Set up the host group to have similar settings to below. Once the lifecycle environment and content view is selected, the proper Puppet environment can be automatically populated.

Host Group Settings

We now need the ntp module to this host group so that any client that is part of this host group will have the ntp Puppet module. Click on the Puppet Classes tab and select ntp.

The final steps is to edit the paramters for this host group. Click on Parameters and you will see the parameters for ntp like below. For this example, I had in mind that all development clients would be part of this host group, so in this case they would look at as their ntp server and iburst would be true.

Host Group Parameters

Once the parameters are in, click Submit. At this point, we have successfully added a custom Puppet module with Smart Class Parameters that can be configured at a host group level.

Verifying the Module on a Host

One last point, I just want to show how you can verify that a Puppet module will run on a host. Attach a host to the above created content view and specify the host group to the one we created above.

  1. Browse to Hosts -> All Hosts and click on the client
  2. Click on the YAML button and this will show what information is being passed to the Puppet agent

In the output, you should see the ntp class like shown below:

YAML Config

We can now log into the host, run puppet agent -tv to force the puppet agent to run right now and if everything is correct the ntpd service is now installed and running and the /etc/ntp.conf file will have the servers we set.

NTP Config

Hopefully you found this article useful! Please reach out if you are interested in learning more about custom Puppet modules and their integration with Satellite!