How to Create Puppet Bolt Tasks: Understanding Modules and Tasks

cloud

It’s been a couple of months since I wrote the last article in my series on using Puppet Bolt. If you didn’t catch the previous articles, check out Puppet Bolt Agentless Automation for Linux and Windows Server, How To Run Commands on Remote Windows Servers Using Puppet Bolt, Use Puppet Bolt Tasks to Manage Windows Server, and Remote Management Using Puppet Bolt and Windows Subsystem for Linux on Petri.

What is a Puppet Bolt task?

In Use Puppet Bolt Tasks to Manage Windows Server, I showed you how to run the built-in tasks to perform management tasks on Windows Server. But that is only going to take you so far. Puppet Bolt tasks are scripts that you can run on Linux or Windows systems. A task contains a script, completely unmodified, written in any language supported by the remote system on which the task will run. The only prerequisite is that tasks designed for *Nix-based systems must specify the path to the interpreter that will run the script. For example, if you want to run a Ruby script on Linux, the first line of the task starts with a shebang (#!) followed by the path to the Ruby interpreter:

#!/opt/puppetlabs/puppet/bin/ruby

Tasks can accept arguments much like any script. Again, if you want to pass arguments, nothing changes in the script. It looks the same as if it were run natively on the target system. One difference might be that you can store metadata for a task in a separate .json file. For instance, you can include a description of what the task does and the parameters it accepts. Tasks can also be run using Puppet plans. So, if you want to coordinate a complex operation, you can sequence tasks using a plan. But that’s for another time.

Creating Puppet Tasks

Puppet tasks live inside modules. A module is just a directory tree that follows a predefined structure. Modules are self-contained blocks of code that can be easily shared and reused. If you want to package a module so that it can be distributed for use elsewhere, you just zip it up as a .tar.gz file. Modules can be downloaded from GitHub or the Puppet Forge and contain tasks and plans. The module folder name is the name of the module. The subfolders and files typically look something like this but by no means is it a strict requirement.

data/
files/
hiera.yaml
lib/
manifests/
metadata.json
plans/
tasks/

For example, if you want to create a module that just contains a task, you only need to include the tasks folder. If you want to distribute a module, it’s best practice to include init.pp in the manifests folder. Init.pp should contain a module class that matches the name of the module. It might look like this, where my_class is the name of the module:

class my_class {
}

But again, it’s not strictly necessary for your tasks to work. And while modules and tasks can have metadata, it’s also not a requirement.

Puppet Modules and Tasks on GitHub and Puppet Forge

If you don’t want to create your own tasks, you can download modules from Puppet Forge or GitHub that contain tasks. If you want to manage Windows Server Update Services (WSUS) using a Bolt task, search the Puppet Forge for modules that contain tasks using a keyword. You can see in the screenshot below that there are several modules that contain tasks for managing WSUS.

How to Create Puppet Bolt Tasks (Image Credit: Russell Smith)
How to Create Puppet Bolt Tasks (Image Credit: Russell Smith)

In the next article in this series, I’ll show you how to create a module, a task, and how to install it.