Puppet includes two Ruby APIs for writing custom functions. This page is about the modern API, which uses the
# /etc/puppetlabs/code/environments/production/modules/mymodule/lib/puppet/functions/mymodule/upcase.rb Puppet::Functions.create_function(:'mymodule::upcase') do dispatch :up do param 'String', :some_string end def up(some_string) some_string.upcase end end
To write a new function in Ruby, use the
Puppet::Functions.create_function method. You don’t need to
require any Puppet libraries to make it available; Puppet handles that automatically when it loads the function file.
create_function method requires:
dispatchmethod and the parameter methods. Signatures are fully described in a separate page.
In summary, with the pieces labled:
Puppet::Functions.create_function(:<FUNCTION NAME>) do dispatch :<METHOD NAME> do param '<DATA TYPE>', :<ARGUMENT NAME (displayed in docs/errors)> ... end def <METHOD NAME>(<ARGUMENT NAME (for local use)>, ...) <IMPLEMENTATION> end end
The filename must match the name of the function, and have the
.rb extension. For namespaced functions, each segment prior to the final one must be a subdirectory of
functions, and the final segment must be the filename.
|Function name||File location|
Functions are autoloaded and made available to other modules unless those modules specify dependencies. Once a function is written and available (in a module where the autoloader can find it), you can call that function in any Puppet manifest that lists the containing module as a dependency, and also from your main manifest.
Note that if a module has a list of dependencies in its metadata.json file, it loads custom functions only from those specific dependencies.
Function names generally resemble these examples:
num2bool(a function that could come from anywhere)
postgresql::acls_to_resource_hash(a function in the
environment::hash_from_api_call(a function in an environment)
Function names are almost the same as class names. They consist of one or more segments. Each segment must start with a lowercase letter, and can include:
If a name has multiple segments, they are separated by the double-colon (
::) namespace separator.
In other words, each segment should match this regular expression:
The full name should match this regular expression:
Function names can be either global or namespaced.
Global names have only one segment (like
str2bool), and can be used in any module or environment.
Global names are shorter, but they’re not guaranteed to be unique — two modules might use the same function name, in which case Puppet won’t necessarily load the one you want.
Namespaced names have multiple segments (like
stdlib::str2bool), and are guaranteed to be unique. The first segment is dictated by the function’s location:
stdlib::str2bool, for a function stored in the
Most functions have two name segments, although it’s legal to use more.
Some illegal function names:
6_pack(must start with a letter)
_hash_from_api_call(must start with a letter)
Find-Resource(can only contain lowercase letters, numbers, and underscores)
When you call the
Puppet::Functions.create_function method, you should pass the function’s name to it as a Ruby symbol. (Although it can accept a string, we recommend always using a symbol.)
To turn a function name into a symbol:
Ruby functions can have multiple signatures. When a function is called, Puppet checks each signature in order, comparing the allowed arguments to the arguments that were actually passed. Arguments are checked using Puppet’s data type system, the same way class parameters are checked.
As soon as Puppet finds a signature that can accept the provided arguments, it calls the associated implementation method, passing the arguments to that method. When the method finishes running and returns a value, Puppet uses that as the function’s return value.
If none of the function’s signatures match the provided arguments, Puppet fails compilation and logs an error message describing the mismatch between the provided and expected arguments.
When function arguments are passed to a Ruby method, they’re converted to Ruby objects. Similarly, the method’s return value is converted to a Puppet data type when the Puppet manifest regains control.
Puppet converts data types between the Puppet language and Ruby as follows:
|Puppet type||Ruby class|
|Lambda (code block)||
|Data type (
||A type class under
When writing iterative functions, use iterative types instead of Puppet types.
To make this API reference easier to use, we’ve split some of its larger topics into separate pages. Please read the following pages to learn the remainder of the Ruby functions API:
dispatchmethod and the parameter methods.