Iterating over multiple items
Arrays are a powerful feature in Puppet; wherever you want to perform the same operation on a list of things, an array may be able to help. You can create an array just by putting its content in square brackets:
$lunch = [ 'franks', 'beans', 'mustard' ]
How to do it…
Here's a common example of how arrays are used:
- Add the following code to your manifest:
$packages = [ 'ruby1.8-dev', 'ruby1.8', 'ri1.8', 'rdoc1.8', 'irb1.8', 'libreadline-ruby1.8', 'libruby1.8', 'libopenssl-ruby' ] package { $packages: ensure => installed }
- Run Puppet and note that each package should now be installed.
How it works…
Where Puppet encounters an array as the name of a resource, it creates a resource for each element in the array. In the example, a new package resource is created for each of the packages in the $packages
array, with the same parameters (ensure => installed
). This is a very compact way to instantiate many similar resources.
There's more…
Although arrays will take you a long way with Puppet, it's also useful to know about an even more flexible data structure: the hash.
Using hashes
A hash is like an array, but each of the elements can be stored and looked up by name (referred to as the key), for example (hash.pp
):
$interface = { 'name' => 'eth0', 'ip' => '192.168.0.1', 'mac' => '52:54:00:4a:60:07' } notify { "(${interface['ip']}) at ${interface['mac']} on ${interface['name']}": }
When we run Puppet on this, we see the following notify in the output:
t@cookbook:~/.puppet/manifests$ puppet apply hash.pp Notice: (192.168.0.1) at 52:54:00:4a:60:07 on etho
Hash values can be anything that you can assign to variables, strings, function calls, expressions, and even other hashes or arrays. Hashes are useful to store a bunch of information about a particular thing because by accessing each element of the hash using a key, we can quickly find the information for which we are looking.
Creating arrays with the split function
You can declare literal arrays using square brackets, as follows:
define lunchprint() { notify { "Lunch included ${name}":}": } } $lunch = ['egg', 'beans', 'chips'] lunchprint { $lunch: }
Now, when we run Puppet on the preceding code, we see the following notice messages in the output:
t@mylaptop ~ $ puppet apply lunchprint.pp ... Notice: Lunch included chips Notice: Lunch included beans Notice: Lunch included egg
However, Puppet can also create arrays for you from strings, using the split
function, as follows:
$menu = 'egg beans chips' $items = split($menu, ' ') lunchprint { $items: }
Running puppet apply
against this new manifest, we see the same messages in the output:
t@mylaptop ~ $ puppet apply lunchprint2.pp ... Notice: Lunch included chips Notice: Lunch included beans Notice: Lunch included egg.
Note that split
takes two arguments: the first argument is the string to be split. The second argument is the character to split on; in this example, a single space. As Puppet works its way through the string, when it encounters a space, it will interpret it as the end of one item and the beginning of the next. So, given the string 'egg beans chips'
, this will be split into three items.
The character to split on can be any character or string:
$menu = 'egg and beans and chips' $items = split($menu, ' and ')
The character can also be a regular expression, for example, a set of alternatives separated by a |
(pipe) character:
$lunch = 'egg:beans,chips' $items = split($lunch, ':|,')