Creating your first Puppet Task for Puppet Enterprise

At PuppetConf 2017, Puppet Tasks were introduced as part of the new project Bolt. A task allows you to run a program on an arbitrary number of nodes. The program can be just about anything, it just needs to be written in a language that the target nodes can run. For Linux, that means pretty much anything – bash, python, perl, ruby, etc. On Windows, you’re a little more limited out of the box – powershell primarily. Bolt is not yet at version 1.0.0, so I suspect language support for Windows will change. You can use Bolt on its own (even without Puppet, apparently), and starting with Puppet Enterprise 2017.3, you can use Bolt at the PE Console as “tasks” in the UI.

For my first task, I simply want to run a single command on a list of nodes. While I can run arbitrary commands with the bolt command line, I want the practice of writing a task. My use case involves an external authentication system that manages users, ssh keys, and sudo configurations. When a change is made, nodes need to pull the changes. Often, a delay there does not matter – the nodes will receive the change soon enough – but sometimes I want the relevant nodes to pick it up immediately. To do so, I need it to run a single perl script, sanitized as /usr/bin/external_auth.pl, and I want to do it on all the nodes with the profile::external_auth class.

Writing the Task

Writing a task is pretty simple (documentation. First, we need to know the layout of the filesystem. In the module where they reside (in my case, the profile module), create a tasks/ folder. Next, think of your task name (e.g. external_auth_update) and the language you’ve chosen (shell to run my single command) and create two files in that directory, <task>.<language> and <task>.json. The task itself is written in the language of choice (do not forget the shebang to start) and does all the work.

Here are the contents of my tasks/external_auth_update.sh:

#!/bin/sh
/usr/bin/external_auth.pl

The JSON file is the metadata about the task. At a bare minimum, you need the description key. There is a complete metadata reference for the other keys. For this simple task, tasks/external_auth_update.json is pretty simple as well:

{
  "description": "Update the external auth configuration"
}

Commit these files to your controlrepo or module and make sure the master receives the files in the production environment so that Puppet Enterprise can find the task.

Running the Task

Launch your web browser and point it at the Puppet Enterprise Console. Once you have authenticated, browse to Run -> Tasks. Click in the Task field and you’ll see your new task show up (apologies for the sanitization, my task isn’t actually called external_auth):

Select your task. We defined no inputs, so move on to selecting nodes. You can select individual nodes, or use Puppet Query Language to select a dynamic list. I chose to select all nodes with a specific class, my profile::external_auth, which is the class that ensures the required binary is present.

Click the Run Job button and you’ll be sent to the Inspect -> Jobs page with your new job selected. The page will update as the job runs and show you any output on stdout/stderr that you did not redirect:

You will note that in the top right corner it has a Run again button, which is great if you need to do this selection again in the future.

Summary

I must admit that I was a little intimidated by the concept of tasks as the first examples I saw were pretty complicated. Now that I have looked into it, it’s far less intimidating knowing how simple I can make my tasks. I spent just 15 minutes getting started on this simple task, and far longer writing this blog post! When I want to add complexity, I know that I can add inputs and parameters to tasks, combine tasks to create Plans, and run tasks and plans via the CLI. I am sure that I will examine some of those possibilities in the future, and when I do, I will share my experiences here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s