How to Create Puppet Bolt Tasks

Last Update: Sep 05, 2024 | Published: Jun 24, 2019

virtual gear hero img

SHARE ARTICLE

 

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 How to Create Puppet Bolt Tasks Part 1: Understanding Modules and Tasks, I explained what Puppet Bolt tasks are and how they are related to modules. If you haven’t read that article, I suggest you do before following the instructions below. In addition, it’s worth reading the other articles in the series to understand how to work with Linux and Puppet Bolt:

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
Remote Management Using Puppet Bolt and Windows Subsystem for Linux

Create a Puppet Module and Task

Before creating a task, we need a module for it to live in. All that’s required is a directory for the module and a subfolder called tasks. In the example below, I’m creating a folder structure for a module called ‘petriusers’ in the default modules directory. The -p switch creates any parent directories of the tasks folder if they don’t already exist. Note that you should swap out /russell/ for the name of your home directory.

mkdir -p /home/russell/.puppetlabs/bolt/modules/petriusers/tasks

I’m going to use a PowerShell script for my task. I need to create the script and then move it to the tasks directory. I’m using vi to create a script file. vi is a text editor for Linux that is installed by default in most distributions. I’ll just copy the contents of a pre-existing script to the file and then save it.

vi history.ps1

To modify a file in vi, you need to press the INSERT key. To break out of INSERT mode, press ESC. To save a file, type a colon (SHIFT + ;), then w followed by q on the command line. ‘W’ stands for write and ‘q’ for quit.

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

Once the script file is saved, move it from the working directory to the tasks folder, not forgetting to swap out /russell/ for your home directory name.

mv history.ps1 /home/russell/.puppetlabs/bolt/modules/petriusers/tasks

Install a Module Using PuppetFile

Now that we have a module and task created, it needs to be installed so that it can be used with Puppet Bolt. Modules are installed using a file called Puppetfile. You specify the modules you want to install in the file and then run a command to install the module(s). My Puppetfile will contain one line that looks like this:

mod 'petriusers', local: true
How to Create Puppet Bolt Tasks (Image Credit: Russell Smith)
How to Create Puppet Bolt Tasks (Image Credit: Russell Smith)

You can see the module name, petriusers, and the local flag is set to true to designate that it shouldn’t be downloaded from Puppet Forge. Again, I’ll create the file using vi and paste the line of code above into the file and save it.

vi Puppetfile

Now let’s move the file to the bolt directory:

mv Puppetfile /home/russell/.puppetlabs/bolt/

Finally, install the tasks listed in Puppetfile:

bolt puppetfile install

We can check the module was installed by listing the available tasks:

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

And that is it! You can now run the task like you would any other. You can see below that the task is referred to by module_name::task_name.

bolt task run petriusers::history -n winrm://server1 -u administrator -p --no-ssl

If your script accepts arguments, just add them as shown below. My script accepts an argument called ‘days’, setting the number of days for which I want to retrieve user login history information from the event log.

bolt task run petriusers::history days=3 -n winrm:// server1 -u administrator -p --no-ssl

In a forthcoming article, I’ll show you how to orchestrate Puppet Bolt tasks using plans.

SHARE ARTICLE